私は、暗号化を使用して何かを開発することに比較的慣れていません。現在、BouncyCastle と AES-GCM を使用して文字列を暗号化および復号化するクラスを作成しようとしています。暗号化を実装する際に考慮しなければならないことについて読みました。それらの 1 つは、常にランダム化された IV を使用する必要があるということでした。問題は、IV で Cipher を初期化しようとするたびに、テキストが適切に復号化されないことです。
次の例外がスローされるだけです。
javax.crypto.AEADBadTagException: mac check in GCM failed
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher$AEADGenericBlockCipher.doFinal(Unknown Source)
at org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher.engineDoFinal(Unknown Source)
at javax.crypto.Cipher.doFinal(Cipher.java:2165)
at BouncyCastleEX.decrypt(BouncyCastleEX.java:78)
at BouncyCastleEX.main(BouncyCastleEX.java:43)
次の方法を使用して、データを暗号化および復号化しています。
private static final String fallbackSalt = "ajefa6tc73t6raiw7tr63wi3r7citrawcirtcdg78o2vawri7t";
private static final int iterations = 2000;
private static final int keyLength = 256;
private static final SecureRandom random = new SecureRandom();
public byte[] encrypt(String plaintext, String passphrase, String salt)
throws Exception {
SecretKey key = generateKey(passphrase, salt);
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding", "BC");
cipher.init(Cipher.ENCRYPT_MODE, key, generateIV(cipher),random);
return cipher.doFinal(plaintext.getBytes());
}
public String decrypt(byte[] encrypted, String passphrase, String salt)
throws Exception {
SecretKey key = generateKey(passphrase, salt);
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding", "BC");
cipher.init(Cipher.DECRYPT_MODE, key, generateIV(cipher),random);
return new String(cipher.doFinal(encrypted));
}
private SecretKey generateKey(String passphrase, String salt)
throws Exception {
PBEKeySpec keySpec = new PBEKeySpec(passphrase.toCharArray(),
salt.getBytes(), iterations, keyLength);
SecretKeyFactory keyFactory = SecretKeyFactory
.getInstance("PBEWITHSHA256AND256BITAES-CBC-BC");
return keyFactory.generateSecret(keySpec);
}
private IvParameterSpec generateIV(Cipher cipher) throws Exception {
byte[] ivBytes = new byte[cipher.getBlockSize()];
random.nextBytes(ivBytes);
return new IvParameterSpec(ivBytes);
}
cipher.init(...) から「generateIV(cipher)」を削除すると、すべて問題なく動作します。しかし、私が知る限り、それは暗号化を非常に弱めます.
これがコードの小さな間違いなのか、それとも私が何も知らない何か他のものなのか、私にはわかりません。
本当にありがとうございました。