在我的Android应用程序中,我使用密钥大小为256的AES CBC模式,我使用此算法以json格式将密码和一些数据存储为字符串,以便以后可以将其解析为常规对象,但一切都很好,但是当我尝试对具有大于300k字节大小的byte []的对象进行加密会发生错误,因为稍后在我解密此数据时,它的大小比原始的要小得多,并且在解密的字符串中间存在一些奇怪的数据,这以后会导致Exception尝试将其从json解析为对象。 我使用Android密钥存储区来存储我的加密/解密密钥。
public String encrypt(SecretKey key, String data, String transformation) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
mCipher = Cipher.getInstance(transformation);
mCipher.init(Cipher.ENCRYPT_MODE, key);
String result = "";
//get iv from cipher
byte[] iv = mCipher.getIV();
//encode to base64 string
String ivString = Base64.encodeToString(iv, Base64.DEFAULT);
//add to start of result and add special separator to know later where to cut
result += ivString+IV_SEPARATOR;
//encrypt data
byte[] encryptedData = mCipher.doFinal(data.getBytes());
//encode to string encrypted data
String encryptedBase64 = Base64.encodeToString(encryptedData, Base64.DEFAULT);
//add encrypted data to iv and separator
result += encryptedBase64;
return result;
}
public String decrypt(Key key, String data, String transformation) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidAlgorithmParameterException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException, UnsupportedEncodingException {
//split data by IV_SEPARATOR to get array of iv and encrypted data [iv, encrypted data]
String[] parts = data.split(IV_SEPARATOR);
if(parts.length != 2){
throw new IllegalArgumentException("No IV was found.");
}
//decode first part of array to iv byte array
byte[] iv = Base64.decode(parts[0], Base64.DEFAULT);
IvParameterSpec spec = new IvParameterSpec(iv);
//init cipher with required transformation and mode
mCipher = Cipher.getInstance(transformation);
mCipher.init(Cipher.DECRYPT_MODE, key, spec);
//decode data from base64 string to byte array
byte[] encryptedData = Base64.decode(parts[1], Base64.DEFAULT);
//decrypt data using cipher
byte[] decryptedData = mCipher.doFinal(encryptedData);
//return Base64.encodeToString(decryptedData, Base64.DEFAULT);
//convert byte array to String and return it;
return new String(decryptedData);
}
密钥生成器功能
@RequiresApi(api = Build.VERSION_CODES.M)
public void generateAndroidKeyStoreSecretKey(String alias) throws NoSuchProviderException, NoSuchAlgorithmException,
InvalidAlgorithmParameterException {
KeyGenerator keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, ANDROID_KEY_STORE);
KeyGenParameterSpec spec = new KeyGenParameterSpec.Builder(alias, KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
.setKeySize(AES_KEY_SIZE) //key size is 256
.setBlockModes(KeyProperties.BLOCK_MODE_CBC)
.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7)
.setRandomizedEncryptionRequired(true)
.build();
keyGenerator.init(spec);
keyGenerator.generateKey();
}
同样,当我加密小字节[]时,一切都很好,但是当加密大字节时,解密时会破坏它。