SJCL サーバー側で暗号化された文字列があり、利用可能なライブラリを使用して Android で復号化する必要があります。PBKDF2 からキーを生成できないという問題に遭遇するまで、BouncyCastle を試しました。現在、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 は、UTF-8 を使用して JsonParser を実行し、Base64 でデコードした後の SJCL からの文字列です。私はそれを受け取り、パスワードを使用して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 文字列を解読する最も簡単な方法を探しています。提案をいただければ幸いです。
ありがとう!