8

在我的应用程序中,我使用 secretKey 加密和解密数据。为此,我正在使用 AES 算法。但是我在解密时遇到异常,使用密钥的三个已加密值中的一个值。

例外是:

Illegal Block Size Exception Input length must be multiple of 16 when decrypting with padded cipher.

下面是我的代码:

加密价值的功能

public static String symmetricEncrypt(String text, String secretKey) {
    BASE64Decoder decoder = new BASE64Decoder();
    byte[] raw;
    String encryptedString;
    SecretKeySpec skeySpec;
    BASE64Encoder bASE64Encoder = new BASE64Encoder();
    byte[] encryptText = text.getBytes();
    Cipher cipher;
    try {
        raw = decoder.decodeBuffer(secretKey);
        skeySpec = new SecretKeySpec(raw, "AES");
        cipher = Cipher.getInstance("AES");
        cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
        encryptedString = bASE64Encoder.encode(cipher.doFinal(encryptText));
    } 
    catch (Exception e) {
        e.printStackTrace();
        return "Error";
    }
    return encryptedString;
}

解密值的函数

public static String symmetricDecrypt(String text, String secretKey) {
    BASE64Decoder decoder = new BASE64Decoder();
    BASE64Decoder base64Decoder = new BASE64Decoder();
    Cipher cipher;
    String encryptedString;
    byte[] encryptText = null;
    byte[] raw;
    SecretKeySpec skeySpec;
    try {
        raw = decoder.decodeBuffer(secretKey);
        skeySpec = new SecretKeySpec(raw, "AES");
        encryptText = base64Decoder.decodeBuffer(text);
        cipher = Cipher.getInstance("AES");
        cipher.init(Cipher.DECRYPT_MODE, skeySpec);
        encryptedString = new String(cipher.doFinal(encryptText));
    } catch (Exception e) {
        e.printStackTrace();
        return "Error";
    }
    return encryptedString;
}

以下是我正在加密和解密的值

String secretKey = "XMzDdG4D03CKm2IxIWQw7g==";
String value1= "ABCD";
String enctypedValue1= "3uweh4pzoVyH1uODQmVNJA==";
String enctypedValue2= "37PTC20w4DMZYjG3f+GWepSvAbEJUccMXwS/lXilLav1qM/PrCTdontw5/82OdC1zzyhDEsFVRGo rV6gXAQcm+Zai15hliiUQ8l8KRMtUl4=";
String value4= "20000";

/**  Ecnryption and decryption of value1 **/
String encryptedValue1= symmetricEncrypt(value1, secretKey);
String decryptedValue1 = symmetricDecrypt(encryptedValue1, secretKey);

/**  Decryption of  enctypedValue1 **/
String decryptedValue2 = symmetricDecrypt(enctypedValue1, secretKey);
System.out.println(decryptedValue2);

/**  Decryption of  enctypedValue2 (Not decrypted)**/
String decryptedValue3 = symmetricDecrypt(enctypedValue2, secretKey);
System.out.println(decryptedValue3);

/**  Ecnryption and decryption of value4 **/
String encryptedValue4= symmetricEncrypt(value4, secretKey);
String decryptedValue4 = symmetricDecrypt(encryptedValue4, secretKey);

在测试函数中,我编写了以下三个测试用例。

  1. 使用密钥加密和解密的新值 (value1)。
  2. 使用相同密钥解密的两个示例加密值(enctypedValue1、enctypedValue2)。encryptedValue2 在使用相同的密钥解密时出现问题。
  3. 使用密钥加密和解密的新值 (value4)。

在解密 encryptedValue2 我得到以下异常:

Illegal Block Size Exception Input length must be multiple of 16 when decrypting with padded cipher

以下是我到目前为止所得出的结论。

  1. 有问题的值在解码时似乎有问题,它返回无法解密的 81 长度数组?

  2. 如果这个问题发生,它应该发生在所有值上。

  3. 这是一个特定于价值的问题,还是与填充有关,或者它在不同的浏览器、不同的操作系统上可能有不同的行为?

4

1 回答 1

12

我能够毫无问题地运行代码。但是,我使用 Apache 的 Base64 进行编码/解码……也许您的 Base64 有错误。如果你自己写,你很可能会错过一些案例。对于真正的生产代码,请使用经过大量测试的库,例如 Apache 的。

你可以在这里找到我用于 Base64 的库:http: //commons.apache.org/proper/commons-codec/download_codec.cgi

这是完整的工作代码:

    package security.symmatric;

    import javax.crypto.Cipher;
    import javax.crypto.spec.SecretKeySpec;

    import org.apache.commons.codec.binary.Base64;

    public class AES {
        public static String symmetricEncrypt(String text, String secretKey) {
            byte[] raw;
            String encryptedString;
            SecretKeySpec skeySpec;
            byte[] encryptText = text.getBytes();
            Cipher cipher;
            try {
                raw = Base64.decodeBase64(secretKey);
                skeySpec = new SecretKeySpec(raw, "AES");
                cipher = Cipher.getInstance("AES");
                cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
                encryptedString = Base64.encodeBase64String(cipher.doFinal(encryptText));
            } 
            catch (Exception e) {
                e.printStackTrace();
                return "Error";
            }
            return encryptedString;
        }

        public static String symmetricDecrypt(String text, String secretKey) {
            Cipher cipher;
            String encryptedString;
            byte[] encryptText = null;
            byte[] raw;
            SecretKeySpec skeySpec;
            try {
                raw = Base64.decodeBase64(secretKey);
                skeySpec = new SecretKeySpec(raw, "AES");
                encryptText = Base64.decodeBase64(text);
                cipher = Cipher.getInstance("AES");
                cipher.init(Cipher.DECRYPT_MODE, skeySpec);
                encryptedString = new String(cipher.doFinal(encryptText));
            } catch (Exception e) {
                e.printStackTrace();
                return "Error";
            }
            return encryptedString;
        }

        public static void main(String[] args) {
            String secretKey = "XMzDdG4D03CKm2IxIWQw7g==";
            String value1= "ABCD";
            String enctypedValue1= "3uweh4pzoVyH1uODQmVNJA==";
            String enctypedValue2= "37PTC20w4DMZYjG3f+GWepSvAbEJUccMXwS/lXilLav1qM/PrCTdontw5/82OdC1zzyhDEsFVRGo rV6gXAQcm+Zai15hliiUQ8l8KRMtUl4=";
            String value4= "20000";

            /**  Ecnryption and decryption of value1 **/
            String encryptedValue1= symmetricEncrypt(value1, secretKey);
            String decryptedValue1 = symmetricDecrypt(encryptedValue1, secretKey);
            System.out.println(decryptedValue1);

            /**  Decryption of  enctypedValue1 **/
            String decryptedValue2 = symmetricDecrypt(enctypedValue1, secretKey);
            System.out.println(decryptedValue2);

            /**  Decryption of  enctypedValue2 **/
            String decryptedValue3 = symmetricDecrypt(enctypedValue2, secretKey);
            System.out.println(decryptedValue3);

            /**  Ecnryption and decryption of value4 **/
            String encryptedValue4= symmetricEncrypt(value4, secretKey);
            String decryptedValue4 = symmetricDecrypt(encryptedValue4, secretKey);
            System.out.println(decryptedValue4);
        }
    }
于 2013-07-11T07:47:51.403 回答