java - 加密 - IV 长度与提供的不同

标签 java encryption jce

我已经在加密方面苦苦挣扎了一段时间,我即将完成该过程,但是,我现在遇到了 IV 的一些问题。这是我的代码:

第四代

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

 return iv; 
}

AES-256 密码创建( key )

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

当我在 Cipher 上调用 getIV 方法时,我得到:

8E12399C07726F5A

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

我仅使用 JCE 库:

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

有人能解释一下吗?如果您需要更多详细信息,请告诉我。

最佳答案

正如 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 存储为 Key,而不是字节数组。

关于java - 加密 - IV 长度与提供的不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13842231/

相关文章:

java - 用于 Java 的 PAR2 库

java - 如何避免字符串重复

java - Jacoco 需要对 Lambdas Java8 进行特殊处理吗?

ssl - 仅使用 TLSv1.2 且不使用 SSLv3 TLSv1.2 :! aNULL :! eNULL 的密码套件规范

使用C语言破解凯撒密码

java - 使用自定义 JCE 安全提供程序而不进行签名

java - 如何在类java中使用表

java - 使用网络代理 (nanoHTTPD) 动态传输[随机访问]加密 (AES-CTR) 视频

java - 检查无限加密是否可用

java - PDFbox 异常 - 线程 "main"java.lang.VerifyError 中出现异常