简体   繁体   中英

javax.crypto.BadPaddingException AES

I am using AESCrypt (gradle :compile 'com.scottyab:aescrypt:0.0.1') to encrypt and decrypt the data.

  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);

The code works perfectly fine in this case, I get the same input as decrypted text.

But, when I try to use already encrypted string using the same method ( AES ) from the site http://aesencryption.net/ as shown in the screenshot:

在此输入图像描述

And copy paste that encrypted text like:

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

And then run the code then I get error saying :

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

在此输入图像描述

But when I use the decrypted text into the same site it works fine as shown in the screenshot below.

在此输入图像描述

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;
    }

Probably due to the algorithm to convert the passphrase 'password' to SecretKeySpec

This is the algorithm in AESCrypt

private static SecretKeySpec GenerateKey (final String password) throws NoSuchAlgorithmException, UnsupportedEncodingException {    
     final MessageDigest digest = MessageDigest.getInstance (HASH_ALGORITHM);
     byte [] bytes = password.getBytes ("UTF-8");
     digest.update (bytes, 0, bytes.length);
     byte [] key = digest.digest ();

     log ("SHA-256 key" key);

     SecretKeySpec secretKeySpec = new SecretKeySpec (key, "AES");
     secretKeySpec return;
  }

And this is the (Java) example aesencryption.net

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

The first one applies SHA256 hashing, and the second SHA-1 after completing up to 16 bytes, so the key is different.

I think you are encrypting and decrypting AES in the right way. You do not need to change anything.

But if you want to be compatible with aesencryption.net, you need to implement the same key generation algorithm. The code is not too good. I try to summarize

//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))));
}

I can also provide my own code extracted from an Android app witch requires to store private user data. Data is ciphered with an AES key protected with an user passphrase

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;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM