C# 使用16字节密码解密AES256
我正在尝试用C#解密加密的base64编码字符串。 我已使用以下在线工具对字符串进行加密: 例如,当我使用密钥“zzzz”加密文本“abcd”时,我得到以下base64字符串: 3crNVWxmpkE+UjT3lPoi0g== 我没有得到的是。。。这只是16字节的数据,而IV本身应该已经是16字节了。 因此,我试图添加填充,但密码器正在抱怨填充。我觉得我错过了什么。请参见下面的“我的解密函数”:C# 使用16字节密码解密AES256,c#,encryption,base64,rijndaelmanaged,C#,Encryption,Base64,Rijndaelmanaged,我正在尝试用C#解密加密的base64编码字符串。 我已使用以下在线工具对字符串进行加密: 例如,当我使用密钥“zzzz”加密文本“abcd”时,我得到以下base64字符串: 3crNVWxmpkE+UjT3lPoi0g== 我没有得到的是。。。这只是16字节的数据,而IV本身应该已经是16字节了。 因此,我试图添加填充,但密码器正在抱怨填充。我觉得我错过了什么。请参见下面的“我的解密函数”: public static string Decrypt(string cipherText, s
public static string Decrypt(string cipherText, string keyString)
{
int Keysize = 256;
var key = Encoding.UTF8.GetBytes(keyString);
if (key.Length < 16)
{
var keycopy = new byte[16];
Array.Copy(key, 0, keycopy, 15 - key.Length, key.Length);
key = keycopy;
}
// Get the complete stream of bytes that represent:
// [32 bytes of Salt] + [32 bytes of IV] + [n bytes of CipherText]
var cipherTextBytesWithSaltAndIv = Convert.FromBase64String(cipherText);
// Get the IV bytes by extracting the next 32 bytes from the supplied cipherText bytes.
var iv = cipherTextBytesWithSaltAndIv.Take(8).ToArray();
if (iv.Length < 16)
{
var ivcopy = new byte[16];
Array.Copy(iv, 0, ivcopy, 15 - iv.Length, iv.Length);
iv = ivcopy;
}
// Get the actual cipher text bytes by removing the first 64 bytes from the cipherText string.
var cipherTextBytes = cipherTextBytesWithSaltAndIv.Skip(8).Take(cipherTextBytesWithSaltAndIv.Length - 8).ToArray();
if (cipherTextBytes.Length < 16)
{
var cipherTextBytescopy = new byte[16];
Array.Copy(cipherTextBytes, 0, cipherTextBytescopy, 15 - cipherTextBytes.Length, cipherTextBytes.Length);
cipherTextBytes = cipherTextBytescopy;
}
try
{
using (var rijndaelManaged = new RijndaelManaged { Key = key, Mode = CipherMode.CBC, Padding = PaddingMode.PKCS7 })
using (var memoryStream = new MemoryStream(cipherTextBytes))
using (var cryptoStream = new CryptoStream(memoryStream,
rijndaelManaged.CreateDecryptor(key, iv),
CryptoStreamMode.Read))
{
return new StreamReader(cryptoStream).ReadToEnd();
}
}
catch (CryptographicException e)
{
Console.WriteLine("A Cryptographic error occurred: {0}", e.Message);
return null;
}
// You may want to catch more exceptions here...
}
公共静态字符串解密(字符串密文、字符串键串)
{
int Keysize=256;
var key=Encoding.UTF8.GetBytes(keyString);
如果(键长<16)
{
var keycopy=新字节[16];
Array.Copy(key,0,keycopy,15-key.Length,key.Length);
密钥=密钥副本;
}
//获取表示以下内容的完整字节流:
//[32字节的Salt]+[32字节的IV]+[n字节的密文]
var ciphertextbyteswithaltandiv=Convert.FromBase64String(密文);
//通过从提供的密文字节中提取接下来的32个字节来获取IV字节。
var iv=带Altandiv.Take(8.ToArray()的密文字节;
如果(iv.长度小于16)
{
var ivcopy=新字节[16];
数组.Copy(iv,0,ivcopy,15-iv.长度,iv.长度);
iv=ivcopy;
}
//通过从密文字符串中删除前64个字节来获取实际的密文字节。
var cipherTextBytes=cipherTextBytesWithSaltAndIv.Skip(8).Take(cipherTextBytesWithSaltAndIv.Length-8.ToArray();
if(cipherTextBytes.Length<16)
{
var cipherTextBytescopy=新字节[16];
Copy(cipherTextBytes,0,cipherTextBytes,15-cipherTextBytes.Length,cipherTextBytes.Length);
cipherTextBytes=cipherTextBytescopy;
}
尝试
{
使用(var rijndaelManaged=new rijndaelManaged{Key=Key,Mode=CipherMode.CBC,Padding=PaddingMode.PKCS7})
使用(var memoryStream=新的memoryStream(cipherTextBytes))
使用(var cryptoStream=新加密流(memoryStream,
rijndaelManaged.CreateDecryptor(密钥,iv),
CryptoStreamMode.Read)
{
返回新的StreamReader(cryptoStream).ReadToEnd();
}
}
捕获(加密异常)
{
WriteLine(“发生加密错误:{0}”,e.Message);
返回null;
}
//您可能希望在此捕获更多异常。。。
}
为什么假设静脉注射在开始时?也许IV总是零,并且是隐式的。由于网页不包含文档,可能它不是测试数据的良好来源。IV对CBC至关重要,它没有说明它是什么,使用了什么填充,也没有说明密钥如何扩展到正确的长度。最好找到一些能产生base64密文的C#代码并使用它。问题是我们的客户正在向我发送加密数据,并提到这个工具说“看,他们可以解密我的字符串,所以你也应该能够解密”以及你说该工具的输出似乎不够长,无法包含IV,您必须询问第三方他们正在使用什么样的IV。AES没有定义IV应该如何与消息一起传递,因此不要期望它为您将其添加到消息中(如果它这样做了,它将以专有方式)。但是,AES确实需要一个固定长度的二进制密钥,而不是任意的ASCII字符串。该网站没有说明如何使文本字符串中的键--“zzzz”不是有效的AES键。