我有这个加密功能:
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==
这是一个已知的错误?我能做些什么来解决这个问题?
最佳答案
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都有一个值,该值表示有多少个填充字节。
当然,如果已经有一个版本,则您实际上不应更改任何内容,因为这只会对使用“行为异常”设备的用户造成错误。
关于android - AES/CFB/PKCS5Padding在不同的Android版本上的行为不同,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/39401521/