1

我一直在努力加密一段时间,我即将完成这个过程,但是,我现在遇到了 IV 的一些问题。这是我的代码:

第四代

public static byte[] createIV(int size) { 
 byte[] iv = new byte[size];
 SecureRandom random = new SecureRandom();
 random.nextBytes(iv);   

 return iv; 
}

AES-256 密码创建(密钥)

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;
}

toHex 方法

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

当我在密码上调用 getIV 方法时,我得到了这个:

8E12399C07726F5A

这恰好是我为 IV 提供的字节数的一半。这目前导致了几个问题,因为服务器可以解密消息的第二部分,但不能解密第一部分。

我只使用 JCE 库:

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

任何人都可以对此有所了解吗?如果您需要更多详细信息,请告诉我。

4

1 回答 1

1

正如CodesInChaosbimsapi的评论中所述,您的错误在于将 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,而不是字节数组。

于 2012-12-12T18:52:37.897 回答