我有一个由 SJCL 服务器端加密的字符串,需要在 Android 中使用任何可用的库进行解密。我尝试了 BouncyCastle,直到遇到无法从 PBKDF2 生成密钥的问题。现在我正在使用 SpongyCastle,但我仍然遇到问题。到目前为止,这是我生成密钥和解密字符串的代码:
private static byte[] decrypt(SecretKey key, byte[] encrypted, byte[] iv) throws Exception {
IvParameterSpec ivSpec = new IvParameterSpec(iv);
Cipher cipher = Cipher.getInstance("AES/CCM/NoPadding");
cipher.init(Cipher.DECRYPT_MODE, key, ivSpec);
byte[] decrypted = cipher.doFinal(encrypted);
return decrypted;
}
public static SecretKey generateKey(char[] passphraseOrPin, byte[] salt) throws NoSuchAlgorithmException, InvalidKeySpecException {
// Number of PBKDF2 hardening rounds to use. Larger values increase
// computation time. You should select a value that causes computation
// to take >100ms.
final int iterations = 1000;
// Generate a 128-bit key
final int outputKeyLength = 128;
/*SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
KeySpec keySpec = new PBEKeySpec(passphraseOrPin, salt, iterations, outputKeyLength);
SecretKey secretKey = secretKeyFactory.generateSecret(keySpec);*/
PKCS5S2ParametersGenerator generator = new PKCS5S2ParametersGenerator(new SHA256Digest());
generator.init(PBEParametersGenerator.PKCS5PasswordToBytes(passphraseOrPin), salt, iterations);
KeyParameter key = (KeyParameter) generator.generateDerivedMacParameters(outputKeyLength);
SecretKey secretKey = new SecretKeySpec(key.getKey(), "AES");
return secretKey;
}
这是我在函数中调用它的方式:
char[] key = * put PBKDF2 password here *;
// Generate key from password
SecretKey decryptionKey = null;
try {
decryptionKey = generateKey(key, decodedObject.get("salt").getAsString().getBytes());
} catch (Exception e) {
Log.e(TAG, e.getMessage());
}
byte[] decryptedTicketBytes = null;
// Decrypt the ticket
try {
decryptedTicketBytes = decrypt(decryptionKey, decodedObject.get("ct").getAsString().getBytes(), decodedObject.get("iv").getAsString().getBytes());
} catch (Exception e) {
Log.e(TAG, e.getMessage());
}
decodedObject 是 SJCL 在通过具有 UTF-8 的 JsonParser 运行并进行 Base64 解码后的字符串。我拿了它,用密码通过SJCL Demo运行它,解密字符串没问题。我必须在这里遗漏一些简单的东西。
我得到的错误是在 cipher.doFinal 步骤上,如下所示:
java.security.InvalidKeyException: nonce must have length from 7 to 13 octets
我不认为 SJCL 在他们的密码上使用没有填充,所以我尝试在 getInstance 上使用“AES/CCM/PKCS5Padding”,但后来出现了这个错误:
javax.crypto.NoSuchPaddingException: Only NoPadding can be used with AEAD modes.
TLDR:我正在寻找在 Android 中解密 SJCL 字符串的最简单方法。建议将不胜感激。
谢谢!