我目前正在Android上使用AES 256实现对称的解密/解密,受此文章的启发: Java 256bit AES Encryption。 我的实现的目的是我想加密数据库中的数据。
对于密钥生成,我使用以下构造函数,该构造函数采用char []密码:
public Cryptography(char[] password) throws NoSuchAlgorithmException,
InvalidKeySpecException, NoSuchPaddingException {
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBEWITHSHA256AND256BITAES-CBC-BC");
KeySpec spec = new PBEKeySpec(password, salt, 1024, 256);
secretKey = new SecretKeySpec(factory.generateSecret(spec).getEncoded(), "AES");
cipher = Cipher.getInstance(AES/CBC/PKCS5Padding);
}
因此,当我在Android中启动Activity时,我初始化了我的Cryptography类的新实例,因此获得了生成的密钥。 salt是一个16字节的固定随机字节[]。这意味着我总是得到相同的密钥。之所以这样。
现在我在一个Activity中得到一个对象之后,我可以使用以下加密和解密方法,并使用相同的密钥:
public byte[] encrypt(String cleartext) throws InvalidKeyException,
IllegalBlockSizeException, BadPaddingException,
UnsupportedEncodingException, InvalidParameterSpecException {
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
byte[] encText = cipher.doFinal(cleartext.getBytes(CHARSET_NAME));
byte[] iv = cipher.getParameters()
.getParameterSpec(IvParameterSpec.class).getIV();
byte[] enc = new byte[IV_SIZE + encText.length];
for (int i = 0; i < enc.length; i++) {
if (i < IV_SIZE)
enc[i] = iv[i];
else if (i < enc.length)
enc[i] = encText[i - IV_SIZE];
}
return enc;
}
public String decrypt(byte[] encryptedText) throws InvalidKeyException,
InvalidAlgorithmParameterException, UnsupportedEncodingException,
IllegalBlockSizeException, BadPaddingException {
byte[] iv = new byte[IV_SIZE];
byte[] dec = new byte[encryptedText.length - IV_SIZE];
for (int i = 0; i < encryptedText.length; i++) {
if (i < IV_SIZE)
iv[i] = encryptedText[i];
else if (i < encryptedText.length)
dec[i - IV_SIZE] = encryptedText[i];
}
cipher.init(Cipher.DECRYPT_MODE, secretKey, new IvParameterSpec(iv));
return new String(cipher.doFinal(dec), CHARSET_NAME);
}
正如您所看到的,每次加密邮件时,我都会使用密文保存一个全新的IV。
总之:我在数据库表中使用ONE加密密钥,ONE random salt和new IV for EVERY字段。
首先,我想在每次加密数据库表中的一个字段时生成一个带有新盐和新IV的新密钥,并将所需的盐和IV与密文一起保存,或者至少保存一个表行。但我之所以这样做的原因是,因为在Android设备上生成密钥需要花费很多时间。我在模拟器上测试过,但生成密钥花了大约两秒钟。这就是我在Activity启动时只生成一个键的原因。
最后我的问题: 通过我的方法,只使用一个密钥就足够安全,但每条消息都有新的随机IV?目前,我没有看到另一种方法,即通过保持与性能的平衡来使其尽可能安全。
我希望我写的很清楚,有人可以给我一些建议。
亲切的问候
xoidberg
答案 0 :(得分:1)
我认为这个问题与你无关(xoidberg),但它可能与其他人有关。
根据我的理解 - 您使用salt从密码创建(安全随机)密钥。如果每个用户都有一个随机(不同)的盐 - 没关系。否则可能会有问题。
我相信这就是你所做的,所以看来(对我来说)没问题。
我只想提一下,通常你想在保存某些值的哈希函数(通常是密码)时使用salt。像MD5或SHA这样的散列函数没有密钥,您必须为此添加随机性。这就是为什么你需要盐,这就是为什么在这种情况下你通常需要为每个值提供随机盐(如果你只是用相同的盐保存密码哈希,可以检测最常见的哈希并了解用户的密码)最常见的哈希是123456)。在您的情况下 - 每个用户都需要一个独特的盐。
关于IV - 你每次都需要一个随机的(所以没关系)。