Android中AES加解密算法是否使用NoPadding?
分析你的AES加密代码问题及修复方案
先拆解你这段代码里的几个关键问题——这些都是加密实现里很容易踩的坑:
1. IV(初始化向量)的严重安全错误
你直接把加密密钥当作IV来使用,这完全违反了加密安全规范:
- CBC模式要求IV必须是随机生成且不可预测的,绝对不能和密钥复用,否则会泄露密钥相关信息,大幅降低加密的安全性。
- AES的块大小是16字节,如果你的密钥长度不是16字节,
encryptionKey.getBytes("UTF-8")得到的数组长度不符合IV要求,会直接抛出InvalidAlgorithmParameterException异常。
2. NoPadding导致的数据长度问题
你使用了NoPadding,但AES是块加密算法,要求待加密数据的长度必须是块大小(16字节)的整数倍。如果你的unencryptedData长度不满足这个条件,cipher.doFinal()会直接抛出IllegalBlockSizeException。实际场景里几乎不会用NoPadding,推荐使用PKCS5Padding(Java中它和PKCS7Padding兼容,能适配任意长度的输入数据)。
3. 密钥长度与JCE权限限制
代码里注释了256-AES,但Java默认的JCE(Java Cryptography Extension)是限制密钥长度的,默认仅支持128位AES。如果要使用256位密钥,需要注意:Java 8u151及之后的版本默认已经放开了限制,但更早版本需要安装JCE无限制权限策略文件。另外,密钥长度必须严格是16(128位)、24(192位)、32(256位)字节,否则SecretKeySpec会抛出异常。
修复后的代码示例
下面是修正后的代码,解决了上述所有问题:
import javax.crypto.Cipher; import javax.crypto.SecretKeySpec; import javax.crypto.spec.IvParameterSpec; import java.security.SecureRandom; public byte[] encryptString(String unencryptedData, String encryptionKey) throws Exception { // 校验密钥长度是否符合AES要求 byte[] keyBytes = encryptionKey.getBytes("UTF-8"); if (keyBytes.length != 16 && keyBytes.length != 24 && keyBytes.length != 32) { throw new IllegalArgumentException("密钥长度必须是16、24或32字节(对应128、192、256位AES)"); } // 随机生成16字节的安全IV byte[] ivBytes = new byte[16]; SecureRandom secureRandom = new SecureRandom(); secureRandom.nextBytes(ivBytes); IvParameterSpec iv = new IvParameterSpec(ivBytes); // 使用PKCS5Padding填充,适配任意长度输入 Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding", "SunJCE"); SecretKeySpec key = new SecretKeySpec(keyBytes, "AES"); cipher.init(Cipher.ENCRYPT_MODE, key, iv); // 执行加密 byte[] encryptedData = cipher.doFinal(unencryptedData.getBytes("UTF-8")); // IV需要和加密数据一起保存/传输,这里将IV拼接在加密数据前(前16字节是IV) byte[] result = new byte[ivBytes.length + encryptedData.length]; System.arraycopy(ivBytes, 0, result, 0, ivBytes.length); System.arraycopy(encryptedData, 0, result, ivBytes.length, encryptedData.length); return result; }
额外注意点
- 解密时需要先从结果中取出前16字节作为IV,再用剩余字节进行解密。
- 不要给
SecureRandom指定固定种子,否则会破坏IV的随机性,降低安全性。 - 实际开发中不要直接
throws Exception,建议捕获NoSuchAlgorithmException、InvalidKeyException等具体异常,让代码更健壮。
内容的提问来源于stack exchange,提问作者Elisha
相关产品推荐
相关产品推荐

