简体   繁体   English

CipherInputStream只读取16个字节(AES / Java)

[英]CipherInputStream only read 16 bytes (AES/Java)

I'm using CipherInputStream and CipherOutputStream to encrypt files using AES. 我正在使用CipherInputStream和CipherOutputStream来使用AES加密文件。

encrypt(...) seems to be working fine, but my decrypt(...) function only decrypt the first 16 bytes of my files. encrypt(...)似乎工作正常,但我的decrypt(...)函数只解密我的文件的前16个字节。

Here is my class : 这是我的班级:

public class AESFiles {

    private byte[] getKeyBytes(final byte[] key) throws Exception {
        byte[] keyBytes = new byte[16];
        System.arraycopy(key, 0, keyBytes, 0, Math.min(key.length, keyBytes.length));
        return keyBytes;
    }

    public Cipher getCipherEncrypt(final byte[] key) throws Exception {
        byte[] keyBytes = getKeyBytes(key);
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        SecretKeySpec secretKeySpec = new SecretKeySpec(keyBytes, "AES");
        IvParameterSpec ivParameterSpec = new IvParameterSpec(keyBytes);
        cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);
        return cipher;
    }

    public Cipher getCipherDecrypt(byte[] key) throws Exception {
        byte[] keyBytes = getKeyBytes(key);
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        SecretKeySpec secretKeySpec = new SecretKeySpec(keyBytes, "AES");
        IvParameterSpec ivParameterSpec = new IvParameterSpec(keyBytes);
        cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec);
        return cipher;
    }

    public void encrypt(File inputFile, File outputFile, byte[] key) throws Exception {
        Cipher cipher = getCipherEncrypt(key);
        FileOutputStream fos = null;
        CipherOutputStream cos = null;
        FileInputStream fis = null;
        try {
            fis = new FileInputStream(inputFile);
            fos = new FileOutputStream(outputFile);
            cos = new CipherOutputStream(fos, cipher);
            byte[] data = new byte[1024];
            int read = fis.read(data);
            while (read != -1) {
                cos.write(data, 0, read);
                read = fis.read(data);
                System.out.println(new String(data, "UTF-8").trim());
            }
            cos.flush();
        } finally {
            fos.close();
            cos.close();
            fis.close();
        }
    }

    public void decrypt(File inputFile, File outputFile, byte[] key) throws Exception {
        Cipher cipher = getCipherDecrypt(key);
        FileOutputStream fos = null;
        CipherInputStream cis = null;
        FileInputStream fis = null;
        try {
            fis = new FileInputStream(inputFile);
            cis = new CipherInputStream(fis, cipher);
            fos = new FileOutputStream(outputFile);
            byte[] data = new byte[1024];
            int read = cis.read(data);
            while (read != -1) {
                fos.write(data, 0, read);
                read = cis.read(data);
                System.out.println(new String(data, "UTF-8").trim());
            }
        } finally {
            fos.close();
            cis.close();
            fis.close();
        }
    }

    public static void main(String args[]) throws Exception {
        byte[] key = "mykey".getBytes("UTF-8");
        new AESFiles().encrypt(new File("C:\\Tests\\secure.txt"), new File("C:\\Tests\\secure.txt.aes"), key);
        new AESFiles().decrypt(new File("C:\\Tests\\secure.txt.aes"), new File("C:\\Tests\\secure.txt.1"), key);
    }
}

So my question is, why the decrypt function only read the first 16 bytes ? 所以我的问题是,为什么decrypt函数只读取前16个字节?

This is very subtle. 这非常微妙。 Your problem is that you are closing your fos before your cos . 你的问题是你 cos 之前关闭你的fos In your encrypt(...) method you are doing: 在您正在执行的encrypt(...)方法中:

} finally {
    fos.close();
    cos.close();
    fis.close();
}

That closes the FileOutputStream out from under the CipherOutputStream so the final padded block of encrypted output never gets written to the output file. 这会从CipherOutputStream下面关闭FileOutputStream ,因此加密输出的最终填充块永远不会写入输出文件。 If you close the fos after the cos then your code should work fine. 如果你在cos 关闭fos那么你的代码应该可以正常工作。

Really, you should consider doing something like: 真的,你应该考虑这样做:

    FileOutputStream fos = null;
    CipherOutputStream cos = null;
    FileInputStream fis = null;
    try {
        fis = new FileInputStream(inputFile);
        fos = new FileOutputStream(outputFile);
        cos = new CipherOutputStream(fos, cipher);
        // once cos wraps the fos, you should set it to null
        fos = null;
        ...
    } finally {
        if (cos != null) {
           cos.close();
        }
        if (fos != null) {
           fos.close();
        }
        if (fis != null) {
           fis.close();
        }
    }

FYI: org.apache.commons.io.IOUtils has a great closeQuietly(...) method which handles null checks and catches the exceptions for you. 仅供参考: org.apache.commons.io.IOUtils有一个很好的closeQuietly(...)方法,可以处理null检查并为您捕获异常。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Java 使用 AES/GCM 加密的 CipherInputStream 直到关闭才会读取 - Java CipherInputStream using AES/GCM encryption wont read until close 将 Java AES 加密转换为 nodejs,但加密后缺少 16 个字节 - Translating Java AES encryption to nodejs, but 16 bytes missing after encryption 将Java转换为PHP:加密AES/CBC/PKCS7Padding,密钥大小:32字节,iv:16字节 - Convert Java to PHP: encrypt AES/CBC/PKCS7Padding, key size: 32 bytes, iv: 16 bytes 用于AES解密的Java字节 - Java Bytes for AES Decryption AES解密无法使用超过16个字节 - AES decryption not working for more than 16 bytes 为什么我的Java卡小程序返回16字节的零而不是AES加密值? - Why my Java Card applet returns 16 bytes of zero instead of AES encrypted value? 为什么Java加密AES填充我的16字节纯文本消息? - Why does Java crypto AES pad my plaintext message which is exactly 16bytes? AES 256位加密-java.security.InvalidAlgorithmParameterException:错误的IV长度:必须为16个字节长 - AES 256 bit encryption - java.security.InvalidAlgorithmParameterException: Wrong IV length: must be 16 bytes long 如何正确读取CipherInputStream? - How to read a CipherInputStream correctly? 为什么用 AES 加密 16 个字节时,密文长度为 32 个字节? - Why is the ciphertext 32 bytes long when encrypting 16 bytes with AES?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM