javax.crypto.BadPaddingException AES

时间:2016-05-24 06:11:20

标签: java android encryption aes

我正在使用AESCrypt (gradle :compile 'com.scottyab:aescrypt:0.0.1') 加密和解密数据。

  TextView  tv=(TextView)findViewById(R.id.demotext);
    String encrypted="",decrypted="";
    try {
        encrypted = AESCrypt.encrypt("password","This is the best thing to go by");

        decrypted = AESCrypt.decrypt("password",encrypted);
    } catch (GeneralSecurityException e) {
        e.printStackTrace();
    }
    System.out.println("EncryptedData:"+encrypted);
    System.out.println("DecryptedData:"+decrypted);
    tv.setText("Encrypted:"+encrypted +"\n"+"Decrypted:"+decrypted);

在这种情况下,代码完全正常,我得到与解密文本相同的输入。

但是,当我尝试使用来自网站http://aesencryption.net/的相同方法( AES )来使用已加密的字符串时,如屏幕截图所示:

enter image description here

复制加密文本的粘贴,如:

decrypted = AESCrypt.decrypt("password","sttA+FbNm3RkTovjHI8CcAdStXiMl45s29Jqle+y+pA=");

然后运行代码然后我收到错误说:

javax.crypto.BadPaddingException: error:1e06b065:Cipher functions:EVP_DecryptFinal_ex:BAD_DECRYPT

enter image description here

但是当我将解密的文本用于同一网站时,它可以正常工作,如下面的屏幕截图所示。

enter image description here

private static byte[] decrypt(byte[] raw, byte[] encrypted) throws Exception {
        SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
        Cipher cipher = Cipher.getInstance("AES");
        cipher.init(Cipher.DECRYPT_MODE, skeySpec);
        byte[] decrypted = cipher.doFinal(encrypted);
        return decrypted;
    }

1 个答案:

答案 0 :(得分:1)

可能是由于算法将密码“密码”转换为SecretKeySpec

这是AESCrypt中的算法

sha = MessageDigest.getInstance ("SHA-1");
key = sha.digest (key);
key = Arrays.copyOf (key, 16); // Use only first 128 bit
SecretKey = new SecretKeySpec (key, "AES");

这是(Java)示例aesencryption.net

//Code from aesencryption.net 
// Generate key
MessageDigest sha = null;
key = myKey.getBytes ("UTF-8");
sha = MessageDigest.getInstance ("SHA-1");
key = sha.digest (key);
key = Arrays.copyOf (key, 16); // Use only first 128 bit
SecretKey = new SecretKeySpec (key, "AES");

public static String encrypt (String strToEncrypt) {
     Cipher cipher = Cipher.getInstance ("AES / ECB / PKCS5Padding");
     cipher.init (Cipher.ENCRYPT_MODE, SecretKey);
     Base64.encodeBase64String return (cipher.doFinal (strToEncrypt.getBytes ("UTF-8"))));
}

public static String decrypt (String strToDecrypt) {
     Cipher cipher = Cipher.getInstance ("AES / ECB / PKCS5PADDING");
     cipher.init (Cipher.DECRYPT_MODE, SecretKey);
     return new String (cipher.doFinal (Base64.decodeBase64 (strToDecrypt))));
}

第一个应用SHA256散列,第二个SHA-1完成后最多16个字节,因此密钥不同。

我认为您正在以正确的方式加密和解密AES。你不需要改变任何东西。

但是如果你想与aesencryption.net兼容,你需要实现相同的密钥生成算法。代码不太好。我试着总结一下

public static String SIMMETRICAL_ALGORITHM = "AES";

//Generate cipher key with user provided password
private static String getPassphraseSize16(String key) {
    if (TextUtils.isEmpty(key)) {
        return null;
    }
    char controlChar = '\u0014';
    String key16 = key + controlChar;
    if (key16.length() < 16) {
        while (key16.length() < 16) {
            key16 += key + controlChar;
        }
    }
    if (key16.length() > 16) {
        key16 = key16.substring(key16.length() - 16, key16.length());
    }
    return key16;
}

//AES cipher with passphrase
public static byte[] encrypt(byte[] message, String passphrase)
        throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
    String passphrase16 = getPassphraseSize16(passphrase);

    SecretKeySpec secretKey = new SecretKeySpec(passphrase16.getBytes(), SIMMETRICAL_ALGORITHM);
    Cipher cipher = Cipher.getInstance(SIMMETRICAL_ALGORITHM);
    cipher.init(Cipher.ENCRYPT_MODE, secretKey);
    byte[] encoded = cipher.doFinal(message);

    return encoded;
}

//AES decipher with passphrase
public static byte[] decrypt(byte[] encodedMessage, String key) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
    String passphrase16 = getPassphraseSize16(key);

    SecretKeySpec secretKey = new SecretKeySpec(passphrase16.getBytes(), SIMMETRICAL_ALGORITHM);
    Cipher cipher = Cipher.getInstance(SIMMETRICAL_ALGORITHM);
    cipher.init(Cipher.DECRYPT_MODE, secretKey);
    byte decoded[] = cipher.doFinal(encodedMessage);

    return decoded;
}

我还可以提供我自己的代码,该代码是从需要存储私人用户数据的Android应用程序中提取的。使用受用户密码保护的AES密钥对数据进行加密

{{1}}
相关问题