我有这个加密功能:

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/

10-11 17:18