I am working with SagePay Forms and currently converting the VB examples they have to c#. I have made good progress so the encryption part of my project works fine (SagePay can decrypt it).
The issue I am having is that when I attempt to decrypt the string, it turns to garbage. If anyone has done this before I would really appreciate some help with my decryption code. I have included the encryption code which works and the first two lines are the setup and call from another method.
I haven't added the VB code but if this is required I could add it. Didn't want a huge post if not required.
Utility Methods:
public string byteArrayToHexString(byte[] ba) { return BitConverter.ToString(ba).Replace("-", ""); } public static byte[] StringToByteArray(string hex) { return Enumerable.Range(0, hex.Length) .Where(x => x % 2 == 0) .Select(x => Convert.ToByte(hex.Substring(x, 2), 16)) .ToArray(); }
Main Encryption Method with first couple of lines being the calling of it extracted from a larger method.
string crypt = "blahblahblah" string EncryptAndEncode = "@" + byteArrayToHexString(aesEncrypt(crypt)); private byte[] aesEncrypt(string inputText) { RijndaelManaged AES = new RijndaelManaged(); //set the mode, padding and block size for the key AES.Padding = PaddingMode.PKCS7; AES.Mode = CipherMode.CBC; AES.KeySize = 128; AES.BlockSize = 128; //convert key and plain text input into byte arrays Byte[] keyAndIvBytes = UTF8Encoding.UTF8.GetBytes("tR7nR6wZHGjYMCuV"); Byte[] inputBytes = UTF8Encoding.UTF8.GetBytes(inputText);//AbHLlc5uLone0D1q //create streams and encryptor object MemoryStream memoryStream = new MemoryStream(); CryptoStream cryptoStream = new CryptoStream(memoryStream, AES.CreateEncryptor(keyAndIvBytes, keyAndIvBytes), CryptoStreamMode.Write); //perform encryption cryptoStream.Write(inputBytes, 0, inputBytes.Length); cryptoStream.FlushFinalBlock(); //get encrypted stream into byte array Byte[] outBytes = memoryStream.ToArray(); //close streams memoryStream.Close(); cryptoStream.Close(); AES.Clear(); return outBytes; }
Decoding and Decrypting methods
public string DecodeAndDecrypt(string strIn) { //** HEX decoding then AES decryption, CBC blocking with PKCS5 padding - DEFAULT ** string DecodeAndDecrypt = aesDecrypt(StringToByteArray(strIn.Substring(1))); return (DecodeAndDecrypt); } private string aesDecrypt(Byte[] inputBytes) { RijndaelManaged AES = new RijndaelManaged(); Byte[] keyAndIvBytes = UTF8Encoding.UTF8.GetBytes("tR7nR6wZHGjYMCuV"); Byte[] outputBytes = inputBytes;//Convert.FromBase64String(inputBytes); //set the mode, padding and block size AES.Padding = PaddingMode.PKCS7; AES.Mode = CipherMode.CBC; AES.KeySize = 128; AES.BlockSize = 128; //create streams and decryptor object MemoryStream memoryStream = new MemoryStream(outputBytes); CryptoStream cryptoStream = new CryptoStream(memoryStream, AES.CreateEncryptor(keyAndIvBytes, keyAndIvBytes), CryptoStreamMode.Read); //perform decryption cryptoStream.Read(outputBytes, 0, outputBytes.Length); Trace.WriteLine(outputBytes); //close streams memoryStream.Close(); cryptoStream.Close(); AES.Clear(); //return System.Text.Encoding.UTF8.GetString(outputBytes); string plainText = Encoding.UTF8.GetString(outputBytes, 0, outputBytes.Length); return plainText; }