android - 在android中生成具有16个字符初始化向量的32个字符的AES字符串
问题描述
我正在使用下面的类在 android 中生成 AES 256 密钥、初始化向量、加密和解密。我面临的问题很少
1)当我调用 getInitializationVector() 时,它返回 24 个字符而不是 16 个。(例如:WoiUFsQpizjG705OXja1Jw==)
2)当我调用 generateKey() 时,它返回 44 个字符而不是 32 个。(例如:tEf+dcrzI4x+kSMS8UZxjwziGySMMkDxO0aVgsj0oBs=)
3)下面的类是对称方法,如何使其不对称。
您可以看到 textKey 和 testIV 的默认值。但我无法创建它。我在堆栈溢出中搜索了解决方案,但是,所有都返回了相同长度的文本。有谁知道如何做到这一点?我做错了吗?提前感谢您宝贵的时间。
public class CryptoDataHandler {
//32 characters
String testKey = "82a645babc5cd41c9a2cb4d0d3ba17ad";
//16 characters
String testIV = "acf30ad32b693849";
String edType = "AES";
String chiperInstanceType = "AES/CBC/PKCS5PADDING";
private static CryptoDataHandler instance = null;
public static CryptoDataHandler getInstance() {
if (instance == null) {
Security.setProperty("crypto.policy", "unlimited");
instance = new CryptoDataHandler();
}
return instance;
}
public String encrypt(String message) throws NoSuchAlgorithmException,
NoSuchPaddingException, IllegalBlockSizeException,
BadPaddingException, InvalidKeyException,
UnsupportedEncodingException, InvalidAlgorithmParameterException {
byte[] srcBuff = message.getBytes(StandardCharsets.UTF_8);
//here using substring because AES takes only 16 or 24 or 32 byte of key
SecretKeySpec skeySpec = new
SecretKeySpec(testKey.substring(0, 32).getBytes(), edType);
IvParameterSpec ivSpec = new
IvParameterSpec(testIV.substring(0, 16).getBytes());
Cipher ecipher = Cipher.getInstance(chiperInstanceType);
ecipher.init(Cipher.ENCRYPT_MODE, skeySpec, ivSpec);
byte[] dstBuff = ecipher.doFinal(srcBuff);
return Base64.encodeToString(dstBuff, Base64.DEFAULT);
}
public String decrypt(String encrypted) throws NoSuchAlgorithmException,
NoSuchPaddingException, InvalidKeyException,
InvalidAlgorithmParameterException, IllegalBlockSizeException,
BadPaddingException, UnsupportedEncodingException {
SecretKeySpec skeySpec = new
SecretKeySpec(testKey.substring(0, 32).getBytes(), edType);
IvParameterSpec ivSpec = new
IvParameterSpec(testIV.substring(0, 16).getBytes());
Cipher ecipher = Cipher.getInstance(chiperInstanceType);
ecipher.init(Cipher.DECRYPT_MODE, skeySpec, ivSpec);
byte[] raw = Base64.decode(encrypted, Base64.DEFAULT);
byte[] originalBytes = ecipher.doFinal(raw);
return new String(originalBytes, StandardCharsets.UTF_8);
}
public String generateKey() {
try {
Key key;
SecureRandom rand = new SecureRandom();
KeyGenerator generator = KeyGenerator.getInstance(edType);
generator.init(256, rand);
key = generator.generateKey();
return Base64.encodeToString(key.getEncoded(), Base64.DEFAULT);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return null;
}
public String getInitializationVector() {
byte[] IV = new byte[16];
SecureRandom random = new SecureRandom();
random.nextBytes(IV);
return Base64.encodeToString(IV, Base64.DEFAULT);
}
}
解决方案
好吧,我找到了解决方案。在这里张贴。如果它对其他人有帮助。
我刚刚修改了我的 KEY 和 IV 生成方法,精确到 32 个和 16 个字符。我已经测试了加密和解密,它工作正常。
public String generateKey() {
try {
Key key;
SecureRandom rand = new SecureRandom();
KeyGenerator generator = KeyGenerator.getInstance(edType);
generator.init(256, rand);
key = generator.generateKey();
return Base64.encodeToString(key.getEncoded(), Base64.DEFAULT).subString(0,32);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return null;
}
public String getInitializationVector() {
byte[] IV = new byte[16];
SecureRandom random = new SecureRandom();
random.nextBytes(IV);
return Base64.encodeToString(IV, Base64.DEFAULT).subString(0,16);
}
推荐阅读
- c# - C#中的循环列表
- sql-server - EF Core 5 可以翻译什么
- ios - 如何在 SwiftUI Mac 应用程序的帮助菜单中显示用户指南?
- laravel - Laravel如何在部署后更改public_path
- r - 如何将具有重复键的字段组合在一起,以逗号分隔
- objective-c - 使用 drawInRect 缩放时 iPad 模拟器中的图像损坏
- r - 使用R将大小不等的字符串列拆分为多列
- qt - 在带有 `osm` 插件的 Kirigami 应用程序中使用 QtLocation Map 时出现 Appcrash
- python - 根据规范列表 conda 安装软件包
- python - ModuleNotFoundError:没有名为“botorch.utils.multi_objective”的模块