以下代码工作正常,但在三星SM-G950F,Android OS 8.0.0上,它崩溃了:
private String encrypt(String value) {
try {
final byte[] bytes = value != null ? value.getBytes(UTF8) : new byte[0];
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBEWithMD5AndDES");
SecretKey key = keyFactory.generateSecret(new PBEKeySpec(SEKRIT));
Cipher pbeCipher = Cipher.getInstance("PBEWithMD5AndDES");
pbeCipher.init(Cipher.ENCRYPT_MODE, key, new PBEParameterSpec(Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID).getBytes(UTF8), 20));
return new String(Base64.encode(pbeCipher.doFinal(bytes), Base64.NO_WRAP), UTF8);
} catch (Exception e) {
return value;
}
}
private String decrypt(String value) {
try {
final byte[] bytes = value != null ? Base64.decode(value, Base64.DEFAULT) : new byte[0];
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBEWithMD5AndDES");
SecretKey key = keyFactory.generateSecret(new PBEKeySpec(SEKRIT));
Cipher pbeCipher = Cipher.getInstance("PBEWithMD5AndDES");
pbeCipher.init(Cipher.DECRYPT_MODE, key, new PBEParameterSpec(Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID).getBytes(UTF8), 20));
return new String(pbeCipher.doFinal(bytes), UTF8);
} catch (Exception e) {
return value;
}
}
这是完整的错误消息:
Caused by java.lang.RuntimeException: javax.crypto.BadPaddingException: pad block corrupted
at com.edaf.utils.ObscuredSharedPreferences.decrypt(SourceFile:185)
at com.edaf.utils.ObscuredSharedPreferences.getString(SourceFile:134)
at com.edaf.utils.Utils.getFromGlobals(SourceFile:145)
我在崩溃时更改了返回值,但我确信它不会帮助
答案 0 :(得分:0)
如果在一台设备上执行加密并且在另一台设备上执行解密,那段代码设计为失败。如果Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID)
返回不同的字符串,则PBEParameterSpec
构造函数的salt
参数将不同。
一旦盐不同,那么将从密码计算不同的密钥,并且您的解密可能失败并出现与填充相关的异常。即使密码相同,salt 用于创建不同的值(仅使用 ,但ID是相当愚蠢的,因为使用相同的ID将导致相同的密码,甚至在不同的应用程序中)。
如果解密没有失败,那么你顺便得到一个垃圾明文。
问题代码中存在无穷无尽的问题,例如使用单个DES和20次迭代计数以及非验证加密。我可以发一页长篇评论,但我建议你阅读一本关于现代加密的书,并尽快修改你的协议。