C # AES Decryption

I work with SagePay forms and am currently converting the VB examples that they have for C #. I have achieved good results, so part of the encryption of my project works fine (SagePay can decrypt it).

The problem I am facing is that when I try to decrypt a string, it turns into garbage. If someone had done this before, I would really appreciate help in my decrypted code. I have included an encryption code that works, and the first two lines are setting up and calling another method.

I have not added VB code, but if necessary, I can add it. Didn't want a huge post if not required.

Useful 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(); } 

The main encryption method with the first pair of lines, which is a call to 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 decoding 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; } 
+4
source share
1 answer

There are many problems on your code. First, in your decryption method, you create a cipher, which must be a decryptor. Secondly, you read the entire block, including padding your algorithm when you decrypt. The following is a class with fixed elements and should return the correct result. However, I suggest you find the best way to store the key, insert your code and create it the way you advertise it, it is not. You must generate your key using RNG (RNGCryptoServiceProvider) and then use it with a secure hashing algorithm such as SHA512, use this output for your key. Then you need to find a good place to store it, I would consider encrypting your web.config file.

 public static class EncryptionHelper { private static byte[] keyAndIvBytes; static EncryptionHelper() { // You'll need a more secure way of storing this, I hope this isn't // the real key keyAndIvBytes = UTF8Encoding.UTF8.GetBytes("tR7nR6wZHGjYMCuV"); } public static 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(); } public static string DecodeAndDecrypt(string cipherText) { string DecodeAndDecrypt = AesDecrypt(StringToByteArray(cipherText)); return (DecodeAndDecrypt); } public static string EncryptAndEncode(string plaintext) { return ByteArrayToHexString(AesEncrypt(plaintext)); } public static string AesDecrypt(Byte[] inputBytes) { Byte[] outputBytes = inputBytes; string plaintext = string.Empty; using (MemoryStream memoryStream = new MemoryStream(outputBytes)) { using (CryptoStream cryptoStream = new CryptoStream(memoryStream, GetCryptoAlgorithm().CreateDecryptor(keyAndIvBytes, keyAndIvBytes), CryptoStreamMode.Read)) { using (StreamReader srDecrypt = new StreamReader(cryptoStream)) { plaintext = srDecrypt.ReadToEnd(); } } } return plaintext; } public static byte[] AesEncrypt(string inputText) { byte[] inputBytes = UTF8Encoding.UTF8.GetBytes(inputText);//AbHLlc5uLone0D1q byte[] result = null; using (MemoryStream memoryStream = new MemoryStream()) { using (CryptoStream cryptoStream = new CryptoStream(memoryStream, GetCryptoAlgorithm().CreateEncryptor(keyAndIvBytes, keyAndIvBytes), CryptoStreamMode.Write)) { cryptoStream.Write(inputBytes, 0, inputBytes.Length); cryptoStream.FlushFinalBlock(); result = memoryStream.ToArray(); } } return result; } private static RijndaelManaged GetCryptoAlgorithm() { RijndaelManaged algorithm = new RijndaelManaged(); //set the mode, padding and block size algorithm.Padding = PaddingMode.PKCS7; algorithm.Mode = CipherMode.CBC; algorithm.KeySize = 128; algorithm.BlockSize = 128; return algorithm; } } 

Calling is easy:

 string crypt = "blahblahblah"; string EncryptAndEncode = EncryptionHelper.EncryptAndEncode(crypt); Console.WriteLine(EncryptAndEncode); Console.WriteLine(EncryptionHelper.DecodeAndDecrypt(EncryptAndEncode)); Console.ReadLine(); 
+6
source

Source: https://habr.com/ru/post/1490117/


All Articles