我一直在努力加密加密一段时间,我即将完成这个过程,但是,我现在遇到了一些问题。这是我的代码:
public static byte[] createIV(int size) {
byte[] iv = new byte[size];
SecureRandom random = new SecureRandom();
random.nextBytes(iv);
return iv;
}
public static Map<String, byte[]> cipherAES() throws NoSuchAlgorithmException {
Map<String, byte[]> aes = new HashMap<String, byte[]>();
aes.put("IV", ConversionUtil.toHex(createIV(16), 16).getBytes());
KeyGenerator keyGen = KeyGenerator.getInstance("AES");
keyGen.init(256);
Key encryptionKey = keyGen.generateKey();
aes.put("key", encryptionKey.getEncoded());
return aes;
}
public static String toHex(byte[] data, int length) {
StringBuffer buf = new StringBuffer();
for (int i = 0; i != length; i++) {
int v = data[i] & 0xff;
buf.append(DIGITS.charAt(v >> 4));
buf.append(DIGITS.charAt(v & 0xf));
}
return buf.toString();
}
SecretKey key = new SecretKeySpec(map.get("key"), 0, map.get("key").length, "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(map.get("IV"), 0, 16));
如果我使用这种格式向密码提供16字节的IV:
8E12399C07726F5A8E12399C07726F5A
当我在Cipher上调用getIV方法时,我得到了这个:
8E12399C07726F5A
这正是我为IV提供的字节的一半。这当前导致了几个问题,因为服务器可以解密消息的第二部分而不是第一部分。
我只使用JCE库:
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
有人可以对此有所了解吗?如果您需要更多详细信息,请与我们联系。
答案 0 :(得分:1)
正如CodesInChaos和bimsapi的评论中所提到的,您的错误在于您将IV值转换为十六进制。对cipherAES()方法的简单修正是:
public static Map<String, byte[]> cipherAES() throws NoSuchAlgorithmException {
Map<String, byte[]> aes = new HashMap<String, byte[]>();
aes.put("IV", createIV(16)); // <-- no need for conversion
KeyGenerator keyGen = KeyGenerator.getInstance("AES");
keyGen.init(256);
Key encryptionKey = keyGen.generateKey();
aes.put("key", encryptionKey.getEncoded());
return aes;
}
另请注意,您的方法设计有点奇怪。将字符串映射返回到字节数组是非常脆弱的并且容易出错。请考虑返回存储这些项的对象。在该对象中,我将密钥存储为Key
,而不是字节数组。