一、环境准备
本教程基于 Hamibot 的 Rhino 引擎
使用了 Java 加密类库(需通过 importClass 导入)
支持 AES/CBC/PKCS5Padding 模式
二、加密流程
- 导入必要类库
importClass('java.security.SecureRandom');
importClass('java.security.MessageDigest');
importClass('javax.crypto.spec.DESKeySpec');
importClass('javax.crypto.SecretKeyFactory');
importClass('javax.crypto.Cipher');
importClass('java.security.NoSuchAlgorithmException');
importClass('javax.crypto.KeyGenerator');
importClass('javax.crypto.SecretKey');
importClass('javax.crypto.spec.SecretKeySpec');
importClass('javax.crypto.KeyGenerator');
importClass('javax.crypto.spec.IvParameterSpec');
- 加密函数实现
function aes_Encrypt(content, key, iv) {
var content = new java.lang.String(content);
var key = new java.lang.String(key);
var iv = new java.lang.String(iv);
var bm = new java.lang.String('UTF-8');
var input = content.getBytes(bm);
var md = MessageDigest.getInstance('SHA-256');
var thedigest = md.digest(key.getBytes('utf-8'));
var skc = new SecretKeySpec(thedigest, 'AES');
var cipher = Cipher.getInstance('AES/CBC/PKCS5Padding');
cipher.init(Cipher.ENCRYPT_MODE, skc, new IvParameterSpec(iv.getBytes()));
var cipherText = util.java.array('byte', cipher.getOutputSize(input.length));
var ctLength = cipher.update(input, 0, input.length, cipherText, 0);
ctLength += cipher.doFinal(cipherText, ctLength);
var result = android.util.Base64.encodeToString(cipherText, 0).trim();
return result;
}
三、解密流程
- 解密函数实现
function aes_Decrypt(encrypted, key, iv) {
var key = new java.lang.String(key);
var iv = new java.lang.String(iv);
var bm = new java.lang.String('UTF-8');
var keyb = key.getBytes(bm);
var md = MessageDigest.getInstance('SHA-256');
var thedigest = md.digest(keyb);
var skey = new SecretKeySpec(thedigest, 'AES');
var dcipher = Cipher.getInstance('AES/CBC/PKCS5Padding');
dcipher.init(Cipher.DECRYPT_MODE, skey, new IvParameterSpec(iv.getBytes()));
var clearbyte = dcipher.doFinal(android.util.Base64.decode(encrypted, 0));
return new java.lang.String(clearbyte);
}
四、使用示例
// 加密测试
var content = 'Hello Hamibot!';
var key = 'mySecretKey12345'; // 建议使用 16/24/32 字节长度
var iv = 'initializationVe'; // 必须 16 字节
var encrypted = aes_Encrypt(content, key, iv);
console.log('加密结果:', encrypted);
// 解密测试
var decrypted = aes_Decrypt(encrypted, key, iv);
console.log('解密结果:', decrypted);
五、注意事项
密钥长度:
- AES-128:16 字节
- AES-192:24 字节
- AES-256:32 字节
- 代码中通过 SHA-256 自动处理密钥长度
IV(初始化向量):
- 必须为 16 字节
- 每次加密应使用不同的 IV(可通过 SecureRandom 生成)
- 需要与加密数据一起存储/传输
安全建议:
- 不要硬编码密钥和 IV
- 使用安全的密钥生成方式(如 KeyGenerator)
- 考虑结合 HMAC 进行完整性验证
编码问题:
- 统一使用 UTF-8 编码
- Base64 用于二进制数据文本化传输
六、常见问题
为什么需要 Base64 编码?
- 加密结果是二进制数据,Base64 编码方便在文本协议中传输
CBC 模式有什么特点?
- 需要初始化向量(IV)
- 相同明文+相同密钥会产生不同密文
- 支持并行解密
建议在实际使用中结合具体业务场景进行安全加固,本示例代码主要用于演示基本原理。