c#AES解密

我正在使用SagePay Forms,目前正在将他们的VB示例转换为c#。 我取得了很好的进展,所以我项目的加密部分工作正常(SagePay可以解密)。

我遇到的问题是,当我尝试解密字符串时,它会变成垃圾。 如果有人这样做之前我真的很感激我的解密代码的一些帮助。 我已经包含了有效的加密代码,前两行是来自另一种方法的设置和调用。

我没有添加VB代码,但如果需要,我可以添加它。 如果不需要,不想要一个巨大的post。

实用方法:

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

主加密方法,前几行是从较大的方法中提取的调用。

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

解码和解密方法

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

您的代码实际上存在多个问题。 首先在你的解密方法中你要创建一个加密器,它应该是一个解密器。 其次,当您进行解密时,您正在读取整个块,包括将算法填充到缓冲区中。 下面是一个固定项目的类,应该返回正确的结果。 但是我建议你找到一种更好的存储密钥的方法,输入你的代码并按照你的方式生成它是不可能的。 您应该使用RNG(RNGCryptoServiceProvider)生成密钥,然后使用安全散列算法(例如SHA512)对其进行哈希处理,将该输出用于密钥。 然后,您需要找到一个存储它的好地方,我会考虑加密您的web.config文件。

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

打电话很容易:

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