我有这个加密功能:
String Encrypt(String text, byte[] keyBytes) throws Exception {
Cipher cipher = Cipher.getInstance("AES/CFB/PKCS5Padding");
SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES");
IvParameterSpec ivSpec = new IvParameterSpec("AAAAAAAAAAAAAAAA".getBytes("UTF-8"));
cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec);
byte[] results = cipher.doFinal(text.getBytes("UTF-8"));
return Base64.encodeToString(results, Base64.URL_SAFE);
}
在大多数Android设备上,它都能正常运行。但是,在某些旧设备上(注3,LG G2,Android 4.4),它不会加密。
这是两个设备之间的比较。 Note3加密错误,Nexus 6没问题。
Note 3
---------
String to encrypt: Hello, world
Encryption key: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]
Encryption result bytes: [108, -63, -66, 117, 62, -78, -108, 22, 12, -128, 119, 22]
Encryption result Base64: bMG-dT6ylBYMgHcW
Nexus 6
---------
String to encrypt: Hello, world
Encryption key: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]
Encryption result bytes: [108, -63, -66, 117, 62, -78, -108, 22, 12, -128, 119, 22, 89, -73, -23, 114]
Encryption result Base64: bMG-dT6ylBYMgHcWWbfpcg==
这是一个已知的错误吗?我可以做些什么来解决这个问题?
答案 0 :(得分:1)
CFB mode of operation是一种流模式,这意味着它不需要填充。因此,旧版本似乎只是忽略了您对PKCS#7填充的请求(与PKCS#5填充相同)。
您有两种选择:
Cipher.getInstance("AES/CFB/PKCS5Padding")
更改为Cipher.getInstance("AES/CFB/NoPadding")
,以便所有版本都生成缩短的输出。Cipher.getInstance("AES/CFB/NoPadding")
并在加密前手动添加填充,并在解密后将其删除。所有padding bytes都有一个值,表示有多少填充字节。 当然,如果你已经有一个版本,你真的不应该改变任何东西,因为这只会给那些使用"行为不端的用户带来错误。设备
答案 1 :(得分:0)
在此处看到上一篇文章:StackOverflow
立即开始想知道你的缓冲区大小以及你如何转换。
Note3和Nexus6在16位字符的Base64字符串中显示相同的结果,但Note3的“结果字节”不包含那么多字节!
你能验证字节数组的长度是否相同,而Note3实际上是否截断了丢失的4个字节?或者,以固定长度16创建两者并在加密后检查。