javax.crypto.BadPaddingException:在解密文件时给定最终块未正确填充

时间:2017-06-03 11:23:15

标签: java aes rsa

我正在尝试使用java编写一个程序来加密和解密文件,但是我在解密函数上遇到错误:

Caused by: javax.crypto.BadPaddingException: Given final block not properly padded

这是加密代码:

public static void EncryptFile(String inFile, PublicKey rsaPublicKey) {

    AesManaged aesManaged = new AesManaged();

    try {
        aesManaged.keySize = 256;
        aesManaged.blockSize = 128;
        aesManaged.mode = "AES/CBC/PKCS5Padding";

        byte[] key = generateKey(aesManaged.keySize);
        byte[] keyEncrypted = encryptKey(key, rsaPublicKey);

        byte[] LenK = new byte[4];
        byte[] LenIV = new byte[4];

        int lKey = keyEncrypted.length;
        LenK = BitConverter.GetBytes(lKey);
        int lIV = aesManaged.IV().length;
        LenIV = BitConverter.GetBytes(lIV);

        // Write the following to the FileStream
        // for the encrypted file (outFs):
        // - length of the key
        // - length of the IV
        // - ecrypted key
        // - the IV
        // - the encrypted cipher content

        String outFile = "test.lamar";
        ByteArrayOutputStream outFs = new ByteArrayOutputStream();

        outFs.write(LenK);
        outFs.write(LenIV);
        outFs.write(keyEncrypted);
        byte[] i = aesManaged.IV();
        outFs.write(i);

        IvParameterSpec ivspec = new IvParameterSpec(aesManaged.IV());

        SecretKeySpec secretKeySpec = new SecretKeySpec(key, "AES");
        Cipher cipher = Cipher.getInstance(aesManaged.mode);
        cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivspec);

        FileInputStream fileIn = new FileInputStream(inFile);
        CipherOutputStream cipherOut = new CipherOutputStream(outFs, cipher);

        int blockSiseByte = aesManaged.blockSize / 8;

        byte[] data = new byte[blockSiseByte];
        int count;
        // Read in the data from the file and encrypt it
        while ((count = fileIn.read(data, 0, blockSiseByte)) != -1) {
            cipherOut.write(data, 0, count);
        }

        try (OutputStream outputStream = new FileOutputStream(outFile)) {
            outFs.writeTo(outputStream);
        }

        // Close the encrypted file
        fileIn.close();
        outFs.close();
        cipherOut.close();


    } catch (Exception e) {
        e.printStackTrace();
    }

}

和解密代码:

    public static void DecryptFile(String inFile, String outFile,
        PrivateKey rsaPrivateKey) {

    FileOutputStream outFs = null;

    try {
        // Create instance of AesManaged for
        // symetric decryption of the data.
        AesManaged aesManaged = new AesManaged();
        {
            aesManaged.keySize = 256;
            aesManaged.blockSize = 128;
            aesManaged.mode = "AES/CBC/PKCS5Padding";

            // Create byte arrays to get the length of
            // the encrypted key and IV.
            // These values were stored as 4 bytes each
            // at the beginning of the encrypted package.
            byte[] LenK = new byte[4];
            byte[] LenIV = new byte[4];

            // Use FileStream objects to read the encrypted
            // file (inFs) and save the decrypted file (outFs).
            {
                byte[] fileBytes = FileUtils.readFileToByteArray(new File(inFile));

                ByteArrayInputStream inFs = new ByteArrayInputStream(
                        fileBytes);
                ;
                for (int i = 0; i < LenK.length; i++) {
                    LenK[i] = (byte) inFs.read();
                }
                for(int i = 0; i< LenIV.length;i++){
                    LenIV[i] = (byte)inFs.read();
                }

                // Convert the lengths to integer values.
                int lenK = BitConverter.ToInt32(LenK, 0);
                int lenIV = BitConverter.ToInt32(LenIV, 0);

                //int startC = lenK + lenIV + 8;
                //int lenC = (int) fileBytes.length - startC;

                // Create the byte arrays for
                // the encrypted AesManaged key,
                // the IV, and the cipher text.
                byte[] KeyEncrypted = new byte[lenK];
                byte[] IV = new byte[lenIV];

                // Extract the key and IV
                for(int i = 0;i<lenK;i++){
                    KeyEncrypted[i] = (byte)inFs.read();
                }
                for(int i =0;i<lenIV;i++){
                    IV[i] = (byte)inFs.read();
                }
                // to decrypt the AesManaged key.
                byte[] KeyDecrypted = decryptKey(KeyEncrypted,rsaPrivateKey);

                Cipher transform = Cipher.getInstance("AES/CBC/PKCS5Padding");
                IvParameterSpec ivspec = new IvParameterSpec(IV);

                SecretKeySpec secretKeySpec = new SecretKeySpec(KeyDecrypted, "AES");

                transform.init(Cipher.DECRYPT_MODE, secretKeySpec, ivspec);
                // Decrypt the key.

                outFs = new FileOutputStream(outFile);

                int count = 0;
                int offset = 0;
                int blockSizeBytes = aesManaged.blockSize / 8;
                byte[] data = new byte[blockSizeBytes];

                CipherInputStream cipherIn = new CipherInputStream(
                        inFs, transform);
                while ((count = cipherIn.read(data, 0, blockSizeBytes)) != -1) {
                    outFs.write(data, 0, count);
                }

                inFs.close();
                cipherIn.close();
            }

        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}

多次迭代后,错误发生在while ((count = cipherIn.read(data, 0, blockSizeBytes)) != -1)行。

我在这里缺少什么?

0 个答案:

没有答案