Java cipher.doFinal() 写入额外的字节

标签 java encryption aes

我正在使用 Java Cipher 和 AES 实现加密/解密。除了在调用 doFinal() 时多写了 5 个字节外,一切都运行良好。因此,我最终得到了一个正确解码的字符串,并附加了 5 个额外的字节。

我认为原因是正在写入整个 16 字节 block 。我看到写入了 3 个 16 字节的 block ,包括最后一个。输入的加密文件为 64 字节。未加密的文本应为 43 个字节。

doFinal 的文档表明它可以返回写入输出缓冲区的字节数。但是,它是 0,16,16,16。我已经尝试了各种形式的 doFinal 和更新,但行为没有任何变化。

它写出一个完整的 block 在某种程度上是有道理的,因为大多数这些算法都是这样运行的。但是,如果它不告诉我输出数据的大小,我应该如何防止多余的数据?

也许我应该使用另一种算法? AES256 是一项要求,但我想知道不同的 block 类型或填充类型是否允许它写入正确的字节数。

有什么指导吗?

为(某些)简洁而删减:

decryptCipher = Cipher.getInstance("AES");
decryptCipher.init(Cipher.DECRYPT_MODE, aesKey);

解密例程的业务部分。

    long bytesToRead = inputFile.length();

    while ((inLen = in.read(buffer)) > 0) {
        int bytesOut = 0;
        byte[] cryptBytes = null;
        int outLen = cipher.getOutputSize(inLen);
        cryptBytes = new byte[outLen];

        if (bytesToRead <= buffer.length) {
            try {
                bytesOut = cipher.doFinal(buffer, 0, inLen, cryptBytes, 0);
            } catch (ShortBufferException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        } else
            try {
                bytesOut = cipher.update(buffer, 0, inLen, cryptBytes, 0);
            } catch (ShortBufferException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

        out.write(cryptBytes, 0, bytesOut);
        bytesToRead -= inLen;

    }
    try {
        out.flush();
        in.close();
        out.close();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

最佳答案

您必须在调用 Cipher.getInstance() 时指定填充机制 - 显然它在加密和解密时必须相同。例如:

decryptCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");

如果没有填充机制,解密方就不知道明文的结尾在哪里(在最后一个 block 内)。

关于Java cipher.doFinal() 写入额外的字节,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1226083/

相关文章:

java - 在程序开始时从 .txt 文件将文件读入 ArrayList

java - 如何将静态jtable限制更改为动态(静态对象数组更改为动态)

haskell - 加密和 ByteString 边界

bash - OpenSSL 解密 AES 256 位(base64)加密密码 - 错误的最终 block 长度

java - Gson将各种数据解析为对象

ssl - 如何禁用 SSL 中的弱密码?

android - 如何在本地存储 SQLcipher 密码

java - SAML RSA 和 AES 解密 - 末尾的随机垃圾字节

c# - Delphi Encrypt Compendium 5.2 与 Chilkat 加密

java - 模拟嵌套循环