密钥异常无效

时间:2017-02-10 04:50:51

标签: encryption cryptography aes public-key-encryption badpaddingexception

我正在从文件中检索文本密码作为输入,然后对其应用AES加密,然后对其进行解密。 当我第一次这样做的时候,它每5次中有4次运行正常(加密解密成功)但是1次,它抛出BadPaddingException。以下是我写的:

//ABCD is class name
public static void enc(String fileName, String pwd) {
    try {
        Properties prop = new Properties();
        InputStream input = ABCD.class.getClassLoader().getResourceAsStream(fileName);
        prop.load(input);
        input.close();
        URL url = ABCD.class.getClassLoader().getResource(fileName);

        FileOutputStream outputStream = new FileOutputStream(url.getPath());
        KeyGenerator key = KeyGenerator.getInstance("AES");

        key.init(128);
        SecretKey aesKey = key.generateKey();
        String newkey = new  String(Base64.encode(aesKey.getEncoded()).getBytes("UTF-8"));

        Cipher aesCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");

        aesCipher.init(Cipher.ENCRYPT_MODE, aesKey);
        byte[] clear = pwd.getBytes("UTF-8");
        byte[] cipher = aesCipher.doFinal(clear);
        String encPwd = new String(cipher);
        prop.setProperty("password", encPwd);
        prop.setProperty("secKey", newkey);
        prop.store(outputStream, null);
        outputStream.close();
    } catch (Exception e) {
        System.out.println(e);
    }
}

public static String dec(Properties prop, String fileName) {

    String decPwd = ABCD.map.get(fileName);
            try {
            String newkey = prop.getProperty("secKey");
            StringBuilder pwd;
            byte[] newkeybuff = Base64.decode(newkey.getBytes("UTF-8"));
            SecretKey key = new SecretKeySpec(newkeyuff, "AES");
            Cipher aesCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            aesCipher.init(Cipher.DECRYPT_MODE, key);
            pwd = new StringBuilder(prop.getProperty("password"));
            byte[] cipher = aesCipher.doFinal(pwd.toString().getBytes());
            decPwd = new String(cipher);
        } catch (Exception e) {
            System.out.println(e);
        }
        ABCD.map.put(fileName, decPwd);
    return decPwd;
}

我需要解决这个问题。在某处,我读到BadPaddingExcpetion发生在使用String完成的操作之后,代替实际应该使用的字节。因此,我将代码更改为以下内容:

public static void enc(String fileName, String pwd) {
    try {
        Properties prop = new Properties();
        InputStream input = ABCD.class.getClassLoader().getResourceAsStream(fileName);
        prop.load(input);
        input.close();
        URL url = ABCD.class.getClassLoader().getResource(fileName);

        FileOutputStream outputStream = new FileOutputStream(url.getPath());
        KeyGenerator key = KeyGenerator.getInstance("AES");

        key.init(128);
        SecretKey aesKey = key.generateKey();

        byte[] newkey=(Base64.encode(aesKey.getEncoded())).getBytes("UTF-8");

        Cipher aesCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");


        aesCipher.init(Cipher.ENCRYPT_MODE, aesKey,new IvParameterSpec(new byte[16]));
        byte[] clear = pwd.getBytes("UTF-8");
        byte[] cipher = aesCipher.doFinal(clear);

        prop.setProperty("password", Arrays.toString(cipher));
        prop.setProperty("secKey", Arrays.toString(newkey));

        prop.store(outputStream, null);
        outputStream.flush();
        outputStream.close();

    } catch (Exception e) {
    System.out.println(e);
}
}

public static String dec(Properties prop, String fileName) {

    String decPwd = ABCD.map.get(fileName);
            try {
            byte[] newkey=prop.getProperty("secKey").getBytes("UTF-8");
            byte[] pwd;


            byte[] newkeybuff = Base64.decode(newkey);
            SecretKeySpec key = new SecretKeySpec(newkeybuff, "AES");

            Cipher aesCipher=Cipher.getInstance("AES/CBC/PKCS5Padding");
            aesCipher.init(Cipher.DECRYPT_MODE, key,new IvParameterSpec(new byte[16]));
            pwd = prop.getProperty("password").getBytes();

            byte[] cipher = aesCipher.doFinal(pwd);

            decPwd=new String(cipher);
            System.out.println("Decrypted pwd " + decPwd);

        } 
        catch (Exception e) {
    System.out.println(e);
}
        ABCD.map.put(fileName, decPwd);

    return decPwd;
}

现在,我收到了InvalidKeyException。这次,我读到密钥的大小应该是16个字节。但我不知道如何应用这个。需要修复此问题!

2 个答案:

答案 0 :(得分:0)

您应该检查您的IV(初始化向量),加密和解密必须相同。

答案 1 :(得分:0)

填充错误通常意味着解密失败。

检查密钥是全长(16,24或32字节),IV是全长(16字节)。如果密钥或IV是短的,它将填充“东西”,并且该人不一致,没有这种填充的标准。

getBytes("UTF-8")可能会返回不同的字节长度,具体取决于使用的字符。

对于IV使用new IvParameterSpec(new byte[16])不正确,IV应该是随机字节。处理IV的一种常用方法是在加密时创建一个随机IV并将其添加到加密数据中,它不需要是秘密的,并且通过预先设置它将可用于解密。