+ Start a Discussion
mnapolimnapoli 

Passing AES Encrypted Data to Salesforce

Ok, so I have a webservice hosted outside of Salesforce that is called from one of our pages within Salesforce. Within this webservice is a field that we need to encrypt before sending it over the wire. I am able to encrypt it but I just keep getting the "Given final block not properly padded" error message when I try to decrypt it in Salesforce. If someone can please take a look at my code and let me know whether the issue lies in my .NET code where I am encrypting it or in my Apex code where I am decrypting it, I would be eternally grateful.

 

My .NET code:

public static string Encrypt_AES(string text)
{
    if (text == null || text.Length <= 0)
    {
        throw new ArgumentNullException("plainText");
    }

    byte[] encrypted;

    using (AesCryptoServiceProvider aesAlg = new AesCryptoServiceProvider())
    {
        aesAlg.Key = System.Text.Encoding.UTF8.GetBytes("ABC123DEF456HIJ789KLM012NOP345QR");
        aesAlg.IV = System.Text.Encoding.UTF8.GetBytes("ABC123DEF456HIJ7");
        aesAlg.Mode = CipherMode.CBC;
        aesAlg.Padding = PaddingMode.PKCS7;

        ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);

        using (MemoryStream ms = new MemoryStream())
        {
            using (CryptoStream cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write))
            {
                using (StreamWriter sw = new StreamWriter(cs))
                {
                    sw.Write(text);
                }

                encrypted = ms.ToArray();
            }
        }
    }

    return Convert.ToBase64String(encrypted);
}

 My Apex code:

blob key = blob.valueOf('ABC123DEF456HIJ789KLM012NOP345QR');
blob iv = blob.valueOf('ABC123DEF456HIJ7');
blob encryptedData = blob.valueOf(response.Text);
blob decryptedData = Crypto.decrypt('AES256', key, iv, encryptedData);				
system.debug(decryptedData.toString());

 

dotNetkowdotNetkow

I had a similar issue - here is a solution that works for decryption on the C# side (reverse of your situation but should still help), via Stack Overflow:

 

string plaintext;
byte[] Key = Convert.FromBase64String("Ii7oSjjWuhp6J6/hj/wmivqx1h3N2HzJ2ByJOy1n89E=");
string encryptedbase64Password = "hRVlbM79aEQi8Tz7JJIL7CEhSxZAJvCh8Ni6ORP1C55+qbJzjDshBYBjyP12/zT2";
byte[] IV = new byte[16];
byte[] phase = Convert.FromBase64String(encryptedbase64Password);
Array.Copy(phase, 0, IV, 0, IV.Length);
byte[] cipherText = new byte[phase.Length - 16];;
Array.Copy(phase, 16, cipherText, 0, cipherText.Length);

using (AesManaged aesAlg = new AesManaged())
{
	aesAlg.KeySize = 256;
	aesAlg.Mode = CipherMode.CBC;
	aesAlg.Padding = PaddingMode.PKCS7;
	aesAlg.Key = Key;
	aesAlg.IV = IV;
	// Create a decrytor to perform the stream transform.
	ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);
	// Create the streams used for decryption.
	using (MemoryStream msDecrypt = new MemoryStream(cipherText))
	{
		using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
		{
			using (StreamReader srDecrypt = new StreamReader(csDecrypt))
			{
				// Read the decrypted bytes from the decrypting stream and place them in a string.
				plaintext = srDecrypt.ReadToEnd();
			}
		}
	}
}