function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
mbondmbond 

System.SecurityException: Given final block not properly padded

I've created a wrapper around Apex's Crypto class so I could have consistent handling of the encrypt and decrypt functions and hide most of the input params to those functions.  I'm storing the 3 blobs that encypt and decrypt as base64 encoded strings and then base64 decoding them before use.  Encyption works fine.  I get this error when decrypting:

 

06:25:30.433|USER_DEBUG|[103]|DEBUG|Key size = 16
06:25:30.433|METHOD_EXIT|[103]|System.debug(ANY)
06:25:30.433|METHOD_ENTRY|[104]|System.debug(ANY)
06:25:30.433|METHOD_ENTRY|[104]|String.valueOf(Integer)
06:25:30.433|METHOD_ENTRY|[104]|Blob.size()
06:25:30.433|METHOD_EXIT|[104]|Blob.size()
06:25:30.433|METHOD_EXIT|[104]|String.valueOf(Integer)
06:25:30.433|USER_DEBUG|[104]|DEBUG|Vector size = 16
06:25:30.433|METHOD_EXIT|[104]|System.debug(ANY)
06:25:30.433|METHOD_ENTRY|[105]|System.debug(ANY)
06:25:30.433|METHOD_ENTRY|[105]|String.valueOf(Integer)
06:25:30.433|METHOD_ENTRY|[105]|Blob.size()
06:25:30.433|METHOD_EXIT|[105]|Blob.size()
06:25:30.433|METHOD_EXIT|[105]|String.valueOf(Integer)
06:25:30.433|USER_DEBUG|[105]|DEBUG|Auth size = 48
06:25:30.433|METHOD_EXIT|[105]|System.debug(ANY)
06:25:30.433|METHOD_ENTRY|[1]|Crypto.Crypto()
06:25:30.433|METHOD_EXIT|[1]|Crypto
06:25:30.433|METHOD_ENTRY|[108]|system.Crypto.decrypt(String, Blob, Blob, Blob)
06:25:30.434|METHOD_EXIT|[108]|system.Crypto.decrypt(String, Blob, Blob, Blob)
06:25:30.436|FATAL_ERROR|System.SecurityException: Given final block not properly padded

I'm using the 128 bit AES option.  You can see from the log that my key, vector, and ciphertext (Auth) are multiple of 8.  I don't want to provide the base64 encoded ciphertext here, but it's 64 characters; however, It does not end in "==".  Since I'm using encrypt to create it, what else must be done to get this to work?  I'm only using ASCII characters in my cleartext when encrypting.  Could SF's implementation of the base64 encoding/decoding not handle round trips with certain characters?

 

Thanks in advance,

Matt

Best Answer chosen by Admin (Salesforce Developers) 
mbondmbond

My problem was simply that the encryption wasn't using the saved values for the key and vector.  Then, when decrypting, it was.  Since the key and vector didn't match, it couldn't decrypt it correctly.

All Answers

mbondmbond

My problem was simply that the encryption wasn't using the saved values for the key and vector.  Then, when decrypting, it was.  Since the key and vector didn't match, it couldn't decrypt it correctly.

This was selected as the best answer
shrishri

Can you please help me to debug my issue..

I  am getting below error...

Visualforce Error


System.SecurityException: Input length must be multiple of 16 when decrypting with padded cipher
An unexpected error has occurred. Your solution provider has been notified. (system)

 

Thanks,

Shri

mbondmbond

Without posting your code, it's hard to debug it.  So here are some general ideas that might point you to the right solution:

1) Your vector should be blob.valueOf(<string of 16 ASCII characters>).

2) Use blob.valueOf() to convert your cleartext into a blob as well.

3) If you are storing the blobs into an object's field (of type string) in SF, then use EncodingUtil.base64Encode and EncodingUtil.base64Decode to set and get the values, respectively.

4) Make sure that any manipulations that you make during the encryption are exactly reversed during decryption.

Hope that helps,

Matt Bond

shrishri

Please find my code below

 

//Below Code is to save encypted code

//            Master controll - This is Long text field 

                  Blob data = Blob.valueOf(casesDetails.Name__c);           
            //Blob data= EncodingUtil.base64Decode(casesDetails.Name__c);
                        // Encrypt the data and have Salesforce.com generate the initialization vector              

            Blob encryptedData = Crypto.encryptWithManagedIV('AES128',cryptoKey, data);
            String b64ecrypted = EncodingUtil.base64Encode(encryptedData);

            casesDetails.Name_c= b64ecrypted ;
            update casesDetails;

 

//To display using below code

       casesDetails = [select id, Name__c from CaseDetails '];
         Blob data2 = Blob.valueOf(casesDetails.Name__c);           

         Blob decryptedData = Crypto.decryptWithManagedIV('AES128', cryptoKey ,data2);

         String b64dcrypted = EncodingUtil.base64Encode(decryptedData);
        casesDetails.Name__c=b64dcrypted;

 

PCan you please check my code let me know If i missing any thing .

mbondmbond

Okay, I see 2 problems.

 

First, you aren't reversing the order of the conversions correctly.

What you have is this

     Encryption:  Start Field > Blob.valueOf > Encrypt > encode > End Field

     Decryption:  End Field > Blob.valueOf > Decrypt > encode > Start Field

What you need is this

     Encryption:  Start Field > Blob.valueOf > Encrypt > encode > End Field

     Decryption:  End Field > decode > Decrypt > Blob.toString > Start Field

 

Second, since the Start Field and End Field are going into the same object's field, how will you know whether you should be encrypting or decrypting the field?  In my code, I encrypt and store in a trigger only if the new field value doesn't match the old field value and the new field value is not blank.  When I decrypt, I never write that value back to the field, but rather use it in code only.

Sulabh KapoorSulabh Kapoor

What is this Start and End field which you have mentioned in the thread. I am folliowing rest of the flow as is.