Gag*_*yan 7 java encryption cryptography sharedpreferences
我有以下加密代码
public static String encrypt(String value, char[] secret) {
try {
final byte[] bytes = value != null ? value.getBytes(StandardCharsets.UTF_8) : new byte[0];
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBEWithMD5AndDES");
SecretKey key = keyFactory.generateSecret(new PBEKeySpec(secret));
Cipher pbeCipher = Cipher.getInstance("PBEWithMD5AndDES");
pbeCipher.init(Cipher.ENCRYPT_MODE, key, new PBEParameterSpec(IsoGame.$().crossPlatformManager.getCrossPlatformUtilsInstance().getDeviceUniqueIdentifier().getBytes(StandardCharsets.UTF_8), 20));
return new String(Base64.encodeBase64(pbeCipher.doFinal(bytes)), StandardCharsets.UTF_8);
} catch (Exception e) {
e.printStackTrace();
}
return value;
}
Run Code Online (Sandbox Code Playgroud)
以及以下解密代码。
public static String decrypt(String value, char[] secret) {
try {
final byte[] bytes = value != null ? Base64.decodeBase64(value.getBytes(StandardCharsets.UTF_8)) : new byte[0];
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBEWithMD5AndDES");
SecretKey key = keyFactory.generateSecret(new PBEKeySpec(secret));
Cipher pbeCipher = Cipher.getInstance("PBEWithMD5AndDES");
pbeCipher.init(Cipher.DECRYPT_MODE, key, new PBEParameterSpec(IsoGame.$().crossPlatformManager.getCrossPlatformUtilsInstance().getDeviceUniqueIdentifier().getBytes(StandardCharsets.UTF_8), 20));
return new String(pbeCipher.doFinal(bytes), StandardCharsets.UTF_8);
} catch (Exception e) {
e.printStackTrace();
}
return value;
}
Run Code Online (Sandbox Code Playgroud)
但是,有时会抛出异常
pbeCipher.doFinal(bytes)
Run Code Online (Sandbox Code Playgroud)
在解密方法中。
例外的是javax.crypto.BadPaddingException: pad block corrupted
这很奇怪,因为我有时会在相同的值下遇到此异常。
有任何想法吗?谢谢。
最可能的原因就是提供了错误的密码。如果提供了错误的密码,则会导出错误的密钥。然后密文将被解密为垃圾明文。仅当引发填充异常时才会注意到这一点:取消填充随机字节可能会失败。
例如,您可以首先通过使用派生密钥对已知数据执行 HMAC 来验证派生密钥是否正确。此外,最好使用某种经过身份验证的加密,这样如果密钥或数据错误或损坏,解密确实会失败。如果你不走运,那么 - 此时 - 数据将解密,取消填充将成功,并且最终会得到垃圾明文。
当然,您最好升级到PBKDF2来进行密钥派生,并将AES升级到例如AES-GCM而不是DES。目前,即使您使用强密码,您的加密也是完全不安全的。