以下示例使用AES加密给定的数据块。加密密钥以安全的方式派生(随机盐,1000轮SHA-256)。加密使用具有随机IV的CBC模式下的AES。
请注意,存储在类数据EncryptedData(salt,iv,和encryptedData)可以被级联以单个字节数组。然后,您可以保存数据或将其传输给收件人。
private static final int SALT_BYTES = 8; private static final int PBK_ITERATIONS = 1000; private static final String ENCRYPTION_ALGORITHM = "AES/CBC/PKCS5Padding"; private static final String PBE_ALGORITHM = "PBEwithSHA256and128BITAES-CBC-BC"; private EncryptedData encrypt(String password, byte[] data) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeySpecException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException, InvalidAlgorithmParameterException { EncryptedData encData = new EncryptedData(); SecureRandom rnd = new SecureRandom(); encData.salt= new byte[SALT_BYTES]; encData.iv= new byte[16]; // AES块大小 rnd.nextBytes(encData.salt); rnd.nextBytes(encData.iv); PBEKeySpec keySpec = new PBEKeySpec(password.toCharArray(), encData.salt, PBK_ITERATIONS); SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance(PBE_ALGORITHM); Key key = secretKeyFactory.generateSecret(keySpec); Cipher cipher = Cipher.getInstance(ENCRYPTION_ALGORITHM); IvParameterSpec ivSpec = new IvParameterSpec(encData.iv); cipher.init(Cipher.ENCRYPT_MODE, key, ivSpec); encData.encryptedData= cipher.doFinal(data); return encData; } private byte[] decrypt(String password, byte[] salt, byte[] iv, byte[] encryptedData) throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException, InvalidAlgorithmParameterException { PBEKeySpec keySpec = new PBEKeySpec(password.toCharArray(), salt, PBK_ITERATIONS); SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance(PBE_ALGORITHM); Key key = secretKeyFactory.generateSecret(keySpec); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); IvParameterSpec ivSpec = new IvParameterSpec(iv); cipher.init(Cipher.DECRYPT_MODE, key, ivSpec); return cipher.doFinal(encryptedData); } private static class EncryptedData { public byte[] salt; public byte[] iv; public byte[] encryptedData; }
以下示例代码显示了如何测试加密和解密:
try { String password = "test12345"; byte[] data = "plaintext11223344556677889900".getBytes("UTF-8"); EncryptedData encData = encrypt(password, data); byte[] decryptedData = decrypt(password, encData.salt, encData.iv, encData.encryptedData); String decDataAsString = new String(decryptedData, "UTF-8"); Toast.makeText(this, decDataAsString, Toast.LENGTH_LONG).show(); } catch (Exception e) { e.printStackTrace(); }