[英]c# AES Decryption
I am working with SagePay Forms and currently converting the VB examples they have to c#. 我正在使用SagePay Forms,目前正在将他们的VB示例转换为c#。 I have made good progress so the encryption part of my project works fine (SagePay can decrypt it).
我取得了很好的进展,所以我的项目的加密部分工作正常(SagePay可以解密)。
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. 我没有添加VB代码,但如果需要,我可以添加它。 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;
}
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.
您应该使用RNG(RNGCryptoServiceProvider)生成密钥,然后使用安全散列算法(例如SHA512)对其进行散列,并将该输出用于密钥。 You then need to find a good place to store it, I would look into encrypting your web.config file.
然后,您需要找到一个存储它的好地方,我会考虑加密您的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;
}
}
Calling it is easy: 打电话很容易:
string crypt = "blahblahblah";
string EncryptAndEncode = EncryptionHelper.EncryptAndEncode(crypt);
Console.WriteLine(EncryptAndEncode);
Console.WriteLine(EncryptionHelper.DecodeAndDecrypt(EncryptAndEncode));
Console.ReadLine();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.