【问题标题】:Question about AES / CBC / PKCS5Padding Decryption in the Java Programming Language关于Java编程语言中AES / CBC / PKCS5Padding解密的问题
【发布时间】:2020-09-26 16:43:46
【问题描述】:

我正在用 Java 开发代码,当用户输入密钥、初始化向量和密文时,程序根据 AES / CBC / PKCS5Padding 模式返回解密后的文本。 此代码不起作用,我希望有人帮助我更正它,或者提供更好的代码。 这个密钥,这个初始化向量和这个密文是从这个网站得到的: https://www.di-mgt.com.au/properpassword.html 也就是说,纯文本必须返回一个简单的“Hello World”消息。 如果您知道任何执行此操作的 Java 代码,请您发表一下吗?

我的代码遇到 NullPointerException 错误:

package encryptdecryptvideo;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.ShortBufferException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
//import javax.crypto.*;

public class EncryptDecryptVideo {

    byte[] input;
    String inputString;
    byte[] keyBytes = "9008873522F55634679EF64CC25E73354".getBytes();
    byte[] ivBytes = "B8A112A270D9634EFF3818F6CCBDF5EC".getBytes();
    
    SecretKeySpec key = new SecretKeySpec(keyBytes, "DES");
    IvParameterSpec ivSpec = new IvParameterSpec(ivBytes);
    Cipher cipher;
    byte[] cipherText = "625F094A1FB1677521B6014321A807EC".getBytes();
    int ctLength;
   
    public static void main(String args[]) throws InvalidKeyException, InvalidAlgorithmParameterException, ShortBufferException, IllegalBlockSizeException, BadPaddingException {
    EncryptDecryptVideo decryptionobject = new EncryptDecryptVideo();
    decryptionobject.decrypt();
    }
    public void decrypt() throws InvalidKeyException, InvalidAlgorithmParameterException, ShortBufferException, IllegalBlockSizeException, BadPaddingException {
       
            cipher.init(Cipher.DECRYPT_MODE, key, ivSpec);
            
            byte[] plainText = new byte[cipher.getOutputSize(ctLength)];
      
            int ptLength = cipher.update(cipherText, 0, ctLength, plainText);
            
            ptLength+= cipher.doFinal(plainText, ptLength);
            
            System.out.println("Plain: "+new String(plainText));
    }
}```

【问题讨论】:

    标签: java encryption aes cbc-mode


    【解决方案1】:

    一些显而易见的点,无需深入:

    首先:没有像 ("AES/CBC/PKCS5Padding") 这样的密码实例化。

    第二:您的“SecretKeySpec”会将输入转换为 DES 密钥(而不是您在标题中要求的“AES”)。

    第三:“cipher.doFinal”调用通常返回一个字节数组,而不是任何整数值。

    第四:您的所有输入数据似乎都是一个十六进制字符串,应该通过“hexStringToByteArray”之类的东西而不是直接通过“.getBytes”转换为字节数组。

    第五:您链接到的网页不使用“密码”作为密码的直接输入,而是执行密码派生(如 PBKDF2),该密码派生也需要在 Java 代码中复制。

    第六:请不要再使用“DES”,因为它已经损坏并且UNSECURE

    我的建议是使用 https://www.di-mgt.com.au/properpassword.html 以外的其他来源进行加密/解密。

    【讨论】:

    • 非常感谢您的回答,Michael Fehr。我有一些问题,请: 1. 如本页所示,有像“AES/CBC/PKCS5Padding”这样的实例化:docs.oracle.com/javase/7/docs/api/javax/crypto/Cipher.html 2. 好的。固定的。 3.在我做的其他代码中,这条线正常工作。 4. 我试图从“.getBytes”更改为“hexStringToByteArray”,但它导致了错误。 5. 好的。 6.好的,非常感谢。我只是在学习。
    • 3.请问,为什么 IDE 没有在此代码行通知错误?
    • 第七:ctlength需要设置为密文长度。第八:只有 ptlength 个字节的明文缓冲区是有效的,但你打印的不止这些。 (Cipher.getOutputSize() 是一个上限,不需要精确,并且对于使用填充解密它不能精确。)该网页,对于所有其他缺陷,确实表示将密文作为十六进制或 b64 不直接作为'string',虽然它对 IV 没有说同样的话,它应该这样做,但它确实这样做了。 Michael:即使没有看到 getInstance,JCE 也不会使用 32bytes=256bits 或 32hex=128bits 的 DES 密钥,或者 IV 同上。
    • @dave_thompson_085:正如我所写,我懒得深入挖掘,也没有检查任何长度,你对 DES-keylengths 和 IV 的看法是对的 :-)
    • @John:对于“hexStringToByteArray”,请在 SO 上查看此答案:stackoverflow.com/a/140861/8166854
    猜你喜欢
    • 1970-01-01
    • 2021-08-13
    • 1970-01-01
    • 2018-11-28
    • 1970-01-01
    • 2022-11-16
    • 1970-01-01
    • 2018-11-13
    • 1970-01-01
    相关资源
    最近更新 更多