解密信用卡号时返回javax.crypto.IllegalBlockSizeException

时间:2015-03-20 15:41:28

标签: java java-ee encryption cryptography

我的加密方法是:

private static final String ALGORITHM = "AES/ECB/PKCS5Padding";
private static final byte[] KEY = "StBet9834#$10BCy".getBytes();

private String encryptCreditCard(String ccNumber) {
    // do some encryption
    if (ccNumber == null || ccNumber.length() == 0) {
        return "";
    }
    Key key = new SecretKeySpec(KEY, "AES");
    try {
        Cipher c = Cipher.getInstance(ALGORITHM);
        c.init(Cipher.ENCRYPT_MODE, key);
        //return Base64.encodeBytes(c.doFinal(ccNumber.getBytes()));
        byte[] ccNumberBytes = ccNumber.getBytes();
        byte[] encCCNumber = c.doFinal(ccNumberBytes);
        return new String(Base64.encodeBase64(encCCNumber));
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}

我使用以下方法解密我的信用卡详细信息:

public void decryptCreditCard() {
  Key key = new SecretKeySpec(KEY, "AES");
  try {
    String ccNumber = this.cardNumber;
    if (ccNumber == null || ccNumber.length() == 0) {
      return;
    }
    Cipher c = Cipher.getInstance(ALGORITHM);
    c.init(Cipher.DECRYPT_MODE, key);
    byte[] ccENCBytes = Base64.decodeBase64(ccNumber);
    byte[] ccDECBytes = c.doFinal(ccENCBytes);
    this.plainCardNumber = new String(ccDECBytes);
    this.last4CreditCard =             plainCardNumber.substring(this.plainCardNumber.length() - 4);
  } catch (Exception e) {
    throw new RuntimeException(e);
  }
}

我的测试卡编号字符串是:5123456789012346。执行此行时:

byte[] ccDECBytes = c.doFinal(ccENCBytes);

我得到以下异常:

Caused by: javax.crypto.IllegalBlockSizeException: Input length must be multiple of 16 when decrypting with padded cipher
  at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:750)
  at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:676)
  at com.sun.crypto.provider.AESCipher.engineDoFinal(AESCipher.java:313)
  at javax.crypto.Cipher.doFinal(Cipher.java:2087)
  at stbet.model.core.CustomerAccount.decryptCreditCard(CustomerAccount.java:527)

此错误表示什么?任何帮助都非常感谢。

1 个答案:

答案 0 :(得分:2)

您的算法必须用填充表示密码:例如:AES / CBC / PKCS5Padding。

编码消息的String表示不能松散字节。你正在使用defualt编码的字符串,所以很可能UTF-8不适合。您需要字节到字节映射,例如:" ISO-8859-1"

返回new String(Base64.encodeBase64(encCCNumber)," ISO-8859-1");

或者只是Base64.encodeBase64String应该完成这项工作;