c# AES Decryption

匿名 (未验证) 提交于 2019-12-03 02:06:01

问题:

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;     } 

回答1:

There are actually multiple problems with your code. First in your decrypt method you're creating an encryptor, that should be a decryptor. Secondly you're reading the entire block including the padding of your algorithm into the buffer when you do the decryption. Below is a class with the items fixed and should be returning the proper result. I do however suggest you find a better way of storing the key, putting in your code and generating it the way you'r edoing it is a no no. You should generate your key with an RNG (RNGCryptoServiceProvider) then hash it with a secure hashing algorithm such as SHA512, use that output for your key. You then need to find a good place to store it, I would look into 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 it is easy:

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


文章来源: c# AES Decryption
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!