【发布时间】:2013-08-13 12:03:37
【问题描述】:
我正在使用 SagePay Forms,目前正在将他们必须的 VB 示例转换为 c#。我已经取得了很好的进展,所以我的项目的加密部分工作正常(SagePay 可以解密)。
我遇到的问题是,当我尝试解密字符串时,它变成了垃圾。如果有人在我之前做过这件事,我将非常感谢我的解密代码的一些帮助。我已经包含了有效的加密代码,前两行是另一种方法的设置和调用。
我还没有添加 VB 代码,但如果需要,我可以添加它。如果不需要,不想要一个大的帖子。
实用方法:
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;
}
【问题讨论】:
-
你在哪里找到的规格?也许您可以包含指向它们的链接。
-
如果你在做解密也许你应该使用
AES.CreateDecryptor而不是AES.CreateEncryptor -
感谢 Greg,您的最后一条评论现在生成了一个可读的字符串,尽管无论出于何种原因,最后仍然有些废话。有点明显,现在我想了想,但看不到它。我会再去解析字符串,看看我是怎么做的。非常感谢,史蒂夫。
-
当然你最后有“废话”。如果使用 PKCS#7 填充机制填充纯文本,则您忘记了纯文本比密文小。您不应忽略
Read方法返回的长度。 -
您正在跳过不必要的障碍。您可以通过一次调用
TransformFinalBlock来替换所有加密流代码。
标签: c# encryption aes opayo