javax.crypto.IllegalBlockSizeException: last block incomplete in decryption - Decrypting an encrypted AES String

前端 未结 3 1364
一个人的身影
一个人的身影 2020-12-29 08:42

I am trying to decrypt the string \"~9?8?m???=?T?G\" that I receive from a back-end server which uses OpenSSL to encrypt the String using AES-256-CBC. There is

相关标签:
3条回答
  • 2020-12-29 09:03

    So thanks to @owlstead, I was able to figure out the solution. It was that I made the mistake of Base64encoding an already Base64 encoded string. The following is by code chunk.

    public static String decryptText(String textToDecrypt) {
        try {
            byte[] decodedValue = Base64.decodeBase64(textToDecrypt.getBytes());
    
            byte[] iv = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
            IvParameterSpec ips = new IvParameterSpec(iv);
    
            byte[] input = textToDecrypt.getBytes();
    
            Cipher cipher = Cipher.getInstance(ENCRYPTION_METHOD);
    
            // decryption pass
            cipher.init(Cipher.DECRYPT_MODE, SECRET_KEY, ips);
            byte[] plainText = cipher.doFinal(decodedValue);
    
            return new String(plainText);
        } catch (Exception e) {
            e.printStackTrace();
            Log.e(TAG, "Decipher error for " + textToDecrypt, e);
        }
    
        return "";
    }
    

    The corresponding encrypting is like this

    public static String encryptText(String textToEncrypt) {
        try {
            byte[] guid = "1234567890123456".getBytes("UTF-8");
    
            byte[] iv = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
            IvParameterSpec ips = new IvParameterSpec(iv);
    
            // The secret key from the server needs to be converted to byte array for encryption.
            byte[] secret = ENCRYPTION_SECRET_HASH.getBytes("UTF-8");
    
            // we generate a AES SecretKeySpec object which contains the secret key.
            // SecretKeySpec secretKey = new SecretKeySpec(secret, "AES");
            Cipher cipher = Cipher.getInstance(ENCRYPTION_METHOD);
            cipher.init(Cipher.ENCRYPT_MODE, SECRET_KEY, ips);
    
            byte[] cipherText = cipher.doFinal(textToEncrypt.getBytes());
            byte[] base64encodedSecretData = Base64.encodeBase64(cipherText);
            String secretString = new String(base64encodedSecretData);
            return secretString;
        } catch (Exception e) {
            e.printStackTrace();
            Log.e(TAG, "Encryption error for " + textToEncrypt, e);
        }
        return "";
    }
    
    0 讨论(0)
  • 2020-12-29 09:10

    Keep the following things in mind while encrypting and decrypting strings,

    ENCRYPTION:

    1. Convert string to byteArray using toByteArray(Charsets.UTF-8) and always specify the charset with UTF-8.

    2. Encrypyt the above byteArray using cipher.doFinal(byteArray).

    3. Now this is not enough, you need to do base64 encoding for that encrypted byteArray using Base64.encode(encryptedByteArray, Base64.DEFAULT)

    4. Remember this again returns byteArray , if you want to convert to string, use toString(Charsets.UTF-8) and most importantly specify the charset again as UTF-8 and then process or store it in DB as you wish.

    DECRYPTION:

    1.Get the encrypted string and first step while decrypting is to decode the encrypted string using base64.decode(encryptedString.toByteArray(Charsets.UTF-8), Base64.DEFAULT)

    1. Now decrypt the decoded byteArray by using cipher.dofinal(decodedByteArray).

    2. Convert the Decrypted byteArray to String using toString(Charsets.UTF-8). NOTE:Always specify the charset. This returns the original string.

    I know I have not shared any code but trust me the flow is the important part while encrypting and decrypting a string..

    0 讨论(0)
  • 2020-12-29 09:18

    You should decode the string instead of encoding the platform specific representation of the string, right at the start of your method.

    byte[] base64TextToDecrypt = Base64.decodeBase64(textToDecrypt);
    

    or more precisely:

    byte[] bytesToDecrypt = Base64(base64TextToDecrypt);
    

    if you name your variables correctly.

    In general, each time you (feel like you have to) use the String.getBytes(): byte[] method or the String(byte[]) constructor you are likely doing something wrong. You should first think about what you are trying to do, and specify a character-encoding if you do need to use it.

    In your case, the output in the converted variable is probably character-encoded. So you you could use the following fragment:

    String plainText = new String(converted, StandardCharsets.UTF_8);
    System.out.println(plainText);
    

    instead of what you have now.

    0 讨论(0)
提交回复
热议问题