解密时出现错误填充异常

时间:2017-07-06 08:47:43

标签: java cryptography passwords aes

我正在尝试实施基于密码的加密算法,但我得到了这个例外:

  

javax.crypto.BadPaddingException:给定最终块没有正确填充

可能是什么问题? (我是Java新手。)这是我的代码:

import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Base64;

public class EfiAdminPasswordHasher {
    /** SIZE variable.*/
    private static final int SIZE = 16;
    /** The serial number. */
    private static final long serialVersionUID = -7930024972049607076L;
    private static final String SECRET_KEY = "Dp29eInG$fch@ujO";
    private static final String SALT = "I@j2ts_@p$c29qTw";
    private SecretKey secretKey;


    public EfiAdminPasswordHasher() {
        generateSecretKey();
    }

    private void generateSecretKey() {
        try {

            SecretKeyFactory factory = SecretKeyFactory
                    .getInstance("PBKDF2WithHmacSHA1");
            KeySpec spec = new PBEKeySpec(SECRET_KEY.toCharArray(),
                    SALT.getBytes(), 65536, 256);
            SecretKey keySpec = factory.generateSecret(spec);
            final SecretKey secret = new SecretKeySpec(keySpec.getEncoded(),
                    "AES");
            System.out.println(secret+" "+"In SECRET kEY");
            secretKey = secret;
        } catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
            throw new IllegalStateException(
                    "EfiAdminPasswordHasher::decryptPassword() - Unable to decrypt password.",
                    e);
        }
    }


public String encryptPassword(String password) {
        if (password == null || password.trim().length() == 0) {
            return password;
        }
        // Encoding password with SHA-256 algorithm
        try {

            MessageDigest md = MessageDigest.getInstance("SHA-256");
            md.update(password.getBytes());

            byte byteData[] = md.digest();
            //convert the byte to hex format method 1
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < byteData.length; i++) {
             sb.append(Integer.toString((byteData[i] & 0xff) + 0x100, 16).substring(1));
            }
            return sb.toString();

        } catch (NoSuchAlgorithmException | IllegalStateException e) {
            throw new IllegalStateException(
                    "EfiAdminPasswordHasher::encryptPassword() - Unable to encrypt password.",
                    e);
        }
    }


public String decryptPassword(String encryptedPassword) {

     // Cannot use StringUtils here, because this class to be serialized and
        // sent over to ACC
        if (encryptedPassword == null || encryptedPassword.trim().length() == 0) {
            return encryptedPassword;
        }
        // DECODE encryptedPwd String
        try {
            final byte[] encrypedPwdBytes = Base64.decodeBase64(encryptedPassword.getBytes());
            final Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");

            byte[] iv = new byte[SIZE];
            cipher.init(Cipher.DECRYPT_MODE, secretKey, new IvParameterSpec(iv));

            final byte[] plainTextPwdBytes = cipher.doFinal(encrypedPwdBytes);

            return new String(plainTextPwdBytes);
        } catch (IllegalBlockSizeException | NoSuchAlgorithmException | NoSuchPaddingException |
                        InvalidKeyException | IllegalStateException | BadPaddingException |
                        InvalidAlgorithmParameterException e) {
            throw new IllegalStateException(
                    "EfiAdminPasswordHasher::decryptPassword() - Unable to decrypt password.",
                    e);
        }
    }


public static void main(String[] args) {
        EfiAdminPasswordHasher hasher = new EfiAdminPasswordHasher();
        String encryptedPassword=hasher.encryptPassword("2");
        System.out.println("Encrypted password"+" "+encryptedPassword);


        String decryptedPassword=hasher.decryptPassword(encryptedPassword);
        System.out.println("Decrypted password"+" "+decryptedPassword);

    }
}

1 个答案:

答案 0 :(得分:0)

我在另一篇帖子here中找到了解决方案,尝试这样做:

final byte[] encrypedPwdBytes = fromHexString(encryptedPassword);
//...
public static byte[] fromHexString(String s) {
    int len = s.length();
    byte[] data = new byte[len / 2];
    for (int i = 0; i < len; i += 2) {
        data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
                             + Character.digit(s.charAt(i+1), 16));
    }
    return data;
}