0
마시맬로에서 일부 데이터를 암호화하고 해독하려고합니다. 암호화는 잘 작동하지만 해독하려고하면 "iv == null"이라고 RuntimeException이 발생합니다.Android Cipher AES/GCM/NoPadding "iv == null"
기본적으로 cipher.getIV() 및 cipher.getParameters()는 null을 반환합니다. 내가 빠진 것이 있습니까? 당신은 해독 할 때 AES/GCM/NoPadding Cipher.init
에 null이 아닌 IV를 제공하기 위해해야
private static final String ALGORITHM_NAME = "AES/GCM/NoPadding";
private static final int IV_SIZE = 128;
private static final int ALGORITHM_SIZE = 256;
private static final String KEYSTORE_PROVIDER = "AndroidKeyStore";
private static final String SYMMETRIC_ALIAS = "secret_key";
private static SecretKey getSymmetricKey()
throws NoSuchProviderException, NoSuchAlgorithmException, InvalidAlgorithmParameterException, IOException,
CertificateException, KeyStoreException, UnrecoverableEntryException {
KeyStore ks = KeyStore.getInstance(KEYSTORE_PROVIDER);
ks.load(null);
return (SecretKey) ks.getKey(SYMMETRIC_ALIAS, null);
}
private static SecretKey createSecretKey()
throws NoSuchAlgorithmException, NoSuchProviderException, InvalidAlgorithmParameterException {
KeyGenerator keyGenerator = KeyGenerator.getInstance(
KeyProperties.KEY_ALGORITHM_AES, KEYSTORE_PROVIDER);
keyGenerator.init(new KeyGenParameterSpec.Builder(SYMMETRIC_ALIAS,
KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
.setBlockModes(KeyProperties.BLOCK_MODE_GCM)
.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
.setKeySize(ALGORITHM_SIZE)
.setRandomizedEncryptionRequired(true)
.setUserAuthenticationRequired(false)
.build());
return keyGenerator.generateKey();
}
public static byte[] encrypt(byte[] data)
throws CertificateException, NoSuchAlgorithmException, IOException, UnrecoverableEntryException,
KeyStoreException, NoSuchProviderException, InvalidAlgorithmParameterException, NoSuchPaddingException,
InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
SecretKey secretKey = getSymmetricKey();
if (secretKey == null) {
secretKey = createSecretKey();
}
Cipher cipher = Cipher.getInstance(ALGORITHM_NAME);
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
return cipher.doFinal(data);
}
public static byte[] decrypt(byte[] data)
throws CertificateException, NoSuchAlgorithmException, IOException, UnrecoverableEntryException,
KeyStoreException, NoSuchProviderException, InvalidAlgorithmParameterException, NoSuchPaddingException,
InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
SecretKey secretKey = getSymmetricKey();
Cipher cipher = Cipher.getInstance(ALGORITHM_NAME);
GCMParameterSpec spec = new GCMParameterSpec(IV_SIZE, cipher.getIV());
cipher.init(Cipher.DECRYPT_MODE, secretKey, spec);
return cipher.doFinal(data.getBytes());
}
IV는 비밀 일 필요는 없지만 GCM에는 고유해야합니다. 길이가 항상 같으므로 해독 전에 암호문 앞에 붙여 넣기 만하면됩니다. –