我在AES256中正确加密字符串时遇到困难。我的要求是它需要是AES256和CBC,长度为24的IV需要加在加密字符串上。我已经提供了一个密钥,它保持不变。
我的代码
public String encrypt(String value) {
try {
SecureRandom secureRandom = new SecureRandom();
byte[] ivBytes = new byte[16];
secureRandom.nextBytes(ivBytes);
SecretKeySpec skeySpec = new SecretKeySpec(byteArray, "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec, new IvParameterSpec(ivBytes));
byte[] encrypted = cipher.doFinal(value.getBytes());
Log.d("encrypted", String.format("%s", encrypted.length));
return Base64.encodeToString(ivBytes, Base64.DEFAULT) + Base64.encodeToString(encrypted, Base64.DEFAULT);
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
这里有几个问题。如果我为ivBytes更改16到24,我会收到一个错误,表示预期iv长度为16而不是24.我也不确定此代码是否在AES256或AES中进行加密。任何帮助表示赞赏。顺便说一句,值是十六进制,例如,它可能是像831684e1。不确定这是否会影响加密。
答案 0 :(得分:1)
这里有几个问题。如果我为ivBytes更改了16到24,我会收到一个错误,指出预期的iv长度是16而不是24。
这是对的。 AES仅定义为128位/ 16字节的块大小。并且CBC 需要单个块大小的随机(化)IV。
我也不确定此代码是否在AES256或AES中进行加密。
我们也不确定,因为未指定byteArray
且Java / Android中的AES实现使用密钥大小在AES-128,-192或-256之间选择。请注意,密钥还应包含随机字节(不是编码为字节的密码)。 Android很好,但对于Java,您可能需要旧版Java Runtime Environment(JRE)的Unlimited Crypto文件。
毋庸置疑,对于AES-256,byteArray
应该是32个字节。
顺便说一句,值是十六进制,例如,它可能是831684e1。不确定这是否会影响加密。
通常十六进制是二进制值的表示。你可能最好首先解码十六进制值,然后加密二进制文件。这将是密文量的一半(并且它也会遵循最少意外的原则)。
目前您正在使用value.getBytes()
这意味着您将获得十六进制的平台特定字符编码(Android的UTF-8,但您基本上得到US-ASCII,因为十六进制总是编码为一个字节每个字符)。换句话说,您将二进制值编码两次,而根本不需要编码。
答案 1 :(得分:0)
这已经解决了。我正在加密正确,我只是没有意识到Base64在我的字符串中附加了一个换行符。这导致网址不正确。因此,为了解决这个问题,我不得不使用Base64.NOWRAP而不是Base64.DEFAULT