JAVA 和 InputStream 中的 AES 加密

AES Encryption in JAVA and InputStream

抱歉,JAVA 初学者。我正在尝试一些加密解密示例。我的方法应该返回一个 InputStream 并且还应该接受一个 Inputstream 作为参数。 该方法的签名如下所示, public static InputStream encriptFile(InputStream inputFile)。 我研究了一下,自信地写了一些代码,但我认为代码没有正确加密示例文件,因为当我解密它并转换为字符串时,它仍然显示乱码。我真的不知道加密和解密 InputStreams 出了什么问题。 Java class 看起来像这样,

    
    private static final String key = "aesEncryptionKey";
    private static final String initVector = "encryptionIntVec";
    
    /*
     * Getting a 128 bit key and iv for encryption
     */
    
    public static InputStream encriptFile(InputStream inputFile) throws IOException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException {
        
        byte[] nonEncryptedByteArray = IOUtils.toByteArray(inputFile);
        
        IvParameterSpec iv = new IvParameterSpec(initVector.getBytes("UTF-8"));
        SecretKeySpec secretkey = new SecretKeySpec(key.getBytes("UTF-8"), "AES");
        
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING"); //Cipher instance using AES encryption algorithm
        cipher.init(Cipher.ENCRYPT_MODE, secretkey, iv);
        byte[] encryptedByteArray = cipher.doFinal(nonEncryptedByteArray);
        
        /*
         * Used the cipher library to encrypt the stream to a byte array
         */
        InputStream encryptedInputStream = new ByteArrayInputStream(encryptedByteArray);
        
        /*
         * Back to streams, but this time encrypted
         */
        
        return encryptedInputStream;
    }
    
    public static InputStream decriptFile(InputStream inputFile) throws IOException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException {
        
        byte[] encrytToDecryptByteArray = IOUtils.toByteArray(inputFile);
        
        IvParameterSpec iv = new IvParameterSpec(initVector.getBytes("UTF-8"));
        SecretKeySpec secretkey = new SecretKeySpec(key.getBytes("UTF-8"), "AES");
        
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
        cipher.init(Cipher.DECRYPT_MODE, secretkey, iv);
        byte[] decryptedByteArray = cipher.doFinal(encrytToDecryptByteArray);
        
        /*
         * dencrypted the encrypted data
         */
        
        InputStream decryptedInputStream = new ByteArrayInputStream(decryptedByteArray);
        
        return decryptedInputStream;
    }

主要方法如下所示,

        
        File file = new File("test.txt");
        InputStream is = new FileInputStream(file);
        
        InputStream eis = encriptFile(is);
        
        StringWriter writer = new StringWriter();
        IOUtils.copy(eis, writer, "UTF-8");
        String theString = writer.toString();
        
        System.out.print(theString);

文本文件的内容是“您好,要加密的文件。让我们看看这是否有效。”。

本应打印出加密输出的输出如下所示。 ��T��� ���N�?]�7!2。当我继续解密它时,它仍然向我显示乱码。很抱歉这个问题很长,感谢您的帮助。

我测试了你的代码,我认为你打印的是加密值(所以,乱码)而不是解密后的值。

如果您将 main 更新为:

public static void main(String[] args) throws Exception {
    InputStream is = new FileInputStream(new File("test.txt"));

    InputStream eis = encriptFile(is);

    InputStream result = decriptFile(eis); // <-- Decryption here

    StringWriter writer = new StringWriter();
    IOUtils.copy(result, writer, "UTF-8");
    String theString = writer.toString();

    System.out.print(theString);
}

你应该没事的。

我只是通过将 decryptFile() 方法更改为进行测试:

public static InputStream decriptFile(InputStream inputFile) throws Exception {

    byte[] encrytToDecryptByteArray = new byte[inputFile.available()];
    inputFile.read(encrytToDecryptByteArray);

    IvParameterSpec iv = new IvParameterSpec(initVector.getBytes(StandardCharsets.UTF_8));
    SecretKeySpec secretkey = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), AES);

    Cipher cipher = Cipher.getInstance(AES_CBC_PKCS_5_PADDING);
    cipher.init(Cipher.DECRYPT_MODE, secretkey, iv);
    byte[] decryptedByteArray = cipher.doFinal(encrytToDecryptByteArray);

    System.out.println(new String(decryptedByteArray));

    return new ByteArrayInputStream(decryptedByteArray);
}

并使用 encriptFile() 的结果调用它并且它正常工作。

你根本不应该 return 输入流。以及您使用流的方式,您实际上并不是在流式传输。如果必须使用流,请使用 CipherInputStream。就个人而言,我总是使用 CipherOutputStream 进行加密,使用 CipherInputStream 进行解密(毕竟,除了从应用程序中导出数据外,您不太可能对加密数据执行任何操作)。

密码和returns二进制数据。这与 UTF-8 不同,文件也不需要编码,因为它们直接接受二进制数据。这可能是当前的问题。只需使用 FileOutputStream / FileInputStream 而不是作者或读者。