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

wad*_*rld 9 java encryption aes

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

我相信原因是正在写入整个1​​6字节的块.我看到写了3个16字节块,包括最后一个.输入加密文件是64字节.未加密的文本应为43个字节.

doFinal的文档表明它可以返回写入输出缓冲区的字节数.但是,它是0,16,16,16.我已尝试过各种形式的doFinal并更新并且不会改变行为.

它是有意义的,它写出一个完整的块,因为这是大多数这些算法的运作方式.但是,如果它不会告诉我输出数据的大小,我该如何防止过多的数据呢?

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

任何指导?

剪断(某些)简洁:

decryptCipher = Cipher.getInstance("AES");
decryptCipher.init(Cipher.DECRYPT_MODE, aesKey);
Run Code Online (Sandbox Code Playgroud)

解密例程的业务部分.

    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();
    }
Run Code Online (Sandbox Code Playgroud)

caf*_*caf 15

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

decryptCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
Run Code Online (Sandbox Code Playgroud)

如果没有填充机制,解密端就没有关于明文结尾位置的信息(在最后一个块内).