在 Java 中解密文本时出现一些错误

Posted

技术标签:

【中文标题】在 Java 中解密文本时出现一些错误【英文标题】:Getting some error while decrypting text in Java 【发布时间】:2022-01-19 07:26:03 【问题描述】:

我有以下用于解密的 NodeJS 代码,它工作得非常好,但是当我当时尝试在 Java 中转换相同的代码时,我遇到了错误。

给定的最终块未正确填充。如果在解密过程中使用了错误的密钥,则可能会出现此类问题

节点JS代码sn-p:

  let textParts = text.split(':');
  let iv = Buffer.from(textParts.shift(), 'hex');
  let encryptedText = Buffer.from(textParts.join(':'), 'hex');
  let decrypted = decipher.update(encryptedText);
  let decipher = crypto.createDecipheriv(
    'aes-256-cbc',
    Buffer.from(ENCRYPTION_KEY),
    iv,
  );
  decrypted = Buffer.concat([decrypted, decipher.final()]);
  return decrypted.toString();

Java 代码 sn-p:

try 
    IvParameterSpec iv = new IvParameterSpec(initVector.getBytes(StandardCharsets.UTF_8));
    SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), "AES");
    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
    cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
    byte[] original = cipher.doFinal(Base64.decodeBase64(encyptedData));
    return new String(original);
 catch (Exception ex) 
    ex.printStackTrace();

Node JS 和 Java 代码的加密密钥相同。 提前致谢。

【问题讨论】:

在 NodeJS 代码中,密文和 IV 是十六进制解码的,在 Java 代码中,IV 是 UTF8 编码的,密文是 Base64 解码的。将 Java 代码中的编码与 NodeJS 代码中的编码相匹配。您还应该在解码明文 (new String(original,...)) 时指定编码。 顺便说一句,在 NodeJS 代码中,createDecipheriv() 调用和 update() 调用被交换了。代码不能像这样执行。 【参考方案1】:

如果你的初始向量是 32 字节,那么你需要解密如下。

public String decrypt(String encryptedData) 
    try 
        String data[] = encryptedData.split(":");
        IvParameterSpec iv = new IvParameterSpec(getBytes(data[0]));
        Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
        SecretKeySpec skeySpec = new SecretKeySpec(YOUR_KEY.getBytes(), "AES");
        cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
        byte[] decryptedData = cipher.doFinal(getBytes(data[1]));
        return new String(decryptedData);
     catch (Exception e) 
        throw new RuntimeException("Error occured while decrypting data", e);
    


public byte[] getBytes(String s)                    
    String tmp;
    byte[] b = new byte[s.length() / 2];
    int i;
    for (i = 0; i < s.length() / 2; i++) 
        tmp = s.substring(i * 2, i * 2 + 2);
        b[i] = (byte)(Integer.parseInt(tmp, 16) & 0xff);
    
    return b;

【讨论】:

NodeJS 代码使用 Utf-8 作为密钥和明文,Java 代码应用平台默认编码。如果这与 Utf-8 不同,则代码不能可靠地工作。因此,最好指定编码!【参考方案2】:

似乎问题在于您解码时 java 中变量的大小。 检查此链接可能会给您一些提示:

1-ejava-base64-encode-and-decode

2-given-final-block-not-properly-padded

【讨论】:

请在您的答案中提供多个链接,因为如果您不提供任何解释,它们可能会被删除***.com/help/deleted-answers

以上是关于在 Java 中解密文本时出现一些错误的主要内容,如果未能解决你的问题,请参考以下文章

在 C# 中使用具有正确私钥和公钥对的 RSA 解密时出现错误数据异常

尝试加密/解密时出现 vigenere 密码错误

解密 Forms cookie 时出现“加密操作期间出错”

解密时出现填充错误,但仍然有效

为 DT 输出渲染文本输入时出现 R 闪亮错误

编译代码时出现 LNK2019 错误