You need to sign in to do that
Don't have an account?

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
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
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.
Can you please help me to debug my issue..
I am getting below 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
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
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 .
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.
What is this Start and End field which you have mentioned in the thread. I am folliowing rest of the flow as is.