有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

JAVA和InputStream中的AES加密

对不起,这里是JAVA初学者。我在尝试一些加密解密的例子。我的方法应该返回一个InputStream,还应该接受一个InputStream作为参数。 这个方法的签名是这样的, public static InputStream encriptFile(InputStream inputFile)。 我进行了一些研究,并自信地编写了一些代码,但我不认为这些代码正确地加密了一个示例文件,因为当我解密它并将其转换为字符串时,它仍然显示出我的胡言乱语。我真的不知道加密和解密输入流出了什么问题。Java类如下所示

    
    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。当我继续解密它时,它仍然显示出我的胡言乱语。很抱歉问了这么长的问题,非常感谢您的帮助


共 (2) 个答案

  1. # 1 楼答案

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

    如果将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()的结果调用它,它工作正常

  2. # 2 楼答案

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

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