Java AES解密中的“给定Final Block未正确填充”错误

时间:2017-04-07 01:38:24

标签: java encryption cryptography aes

我正在制作一个读取加密文件的Java程序,并且在密钥的帮助下,它将对其进行解密。我正在使用这个AES Encryption算法,因为它提供了我也需要的代码。

我所做的是将Java类复制到我的项目中。这就是我的AES.java文件的样子:

public class AES{
    private static SecretKeySpec secretKey ;
    private static byte[] key ;

    private static String decryptedString;
    private static String encryptedString;


    public static void setKey(String myKey){


        MessageDigest sha = null;
        try {
            key = myKey.getBytes("UTF-8");
            System.out.println(key.length);
            sha = MessageDigest.getInstance("SHA-1");
            key = sha.digest(key);
            key = Arrays.copyOf(key, 16); // use only first 128 bit
            System.out.println(key.length);
            System.out.println(new String(key,"UTF-8"));
            secretKey = new SecretKeySpec(key, "AES");


        } catch (NoSuchAlgorithmException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }




    }

    public static String getDecryptedString() {
        return decryptedString;
    }

    public static void setDecryptedString(String decryptedString) {
        AES.decryptedString = decryptedString;
    }

    public static String getEncryptedString() {
        return encryptedString;
    }

    public static void setEncryptedString(String encryptedString) {
        AES.encryptedString = encryptedString;
    }

    public static String encrypt(String strToEncrypt){
        try{
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");

            cipher.init(Cipher.ENCRYPT_MODE, secretKey);

            setEncryptedString(Base64.encodeBase64String(cipher.doFinal(strToEncrypt.getBytes("UTF-8"))));
            //              byte[] encodedBytes = Base64.getEncoder().encode(strToEncrypt.getBytes("UTF-8"));
            //              setEncryptedString(new String(encodedBytes));

        }
        catch (Exception e)
        {

            System.out.println("Error while encrypting: "+e.toString());
        }
        return null;

    }

    public static String decrypt(String strToDecrypt){
        try{
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5PADDING");

            cipher.init(Cipher.DECRYPT_MODE, secretKey);
            setDecryptedString(new String(cipher.doFinal(Base64.decodeBase64(strToDecrypt))));
            //setDecryptedString(new String(cipher.doFinal(Base64.getDecoder().decode(strToDecrypt))));


        }
        catch (Exception e){

            System.out.println("Error while decrypting: "+e.toString());

        }
        return null;
    }


    public static void main(String args[]){

        final String strToEncrypt = "My text to encrypt";
        final String strPssword = "encryptor key";
        AES.setKey(strPssword);

        AES.encrypt(strToEncrypt.trim());

        System.out.println("String to Encrypt: " + strToEncrypt); 
        System.out.println("Encrypted: " + AES.getEncryptedString());

        final String strToDecrypt =  AES.getEncryptedString();
        AES.decrypt(strToDecrypt.trim());

        System.out.println("String To Decrypt : " + strToDecrypt);
        System.out.println("Decrypted : " + AES.getDecryptedString());
    }
}

在我的Main.java课程中:我有以下内容:

//I get my encoded input as a FileInputStream
InputStream encodedInput = null;
encodedInput = new FileInputStream("./Config/config2.properties");

//get the input and then convert to Bytes then to String
//I also tried converting to String right away
byte[] inputBytes = IOUtils.toByteArray(encodedInput);
String theString = IOUtils.toString(inputBytes, "UTF-8"); //IOUtils.toString(encodedInput, "UTF-8"); 
System.out.println("Input string (encoded) = " + theString);

//It stops at the decrypt call and throw the exception
AES.setKey(localProperties.getKey());
AES.decrypt(theString.trim());
String decrypted = AES.getDecryptedString();

如您所见,获取我文件的内容。内容是正确的,因为我也在系统日志中打印它们。

但我无法弄清楚的是,即使函数要求String作为输入,解密函数也无法解密它。

我真的傻眼了,我不知道从哪里开始。

1 个答案:

答案 0 :(得分:2)

public static String decrypt(String strToDecrypt){

问题出在这里。此方法应接受byte[]参数。您已将密文作为byte[]数组。你毫无意义地将它转换为String,只需将其转换回此方法。往返不是无损的。只需将其传递为byte[]数组。

String不是二进制数据的容器。