【发布时间】:2021-01-21 01:11:02
【问题描述】:
加解密方法来自微软documentation。
我有两套不同的钥匙。当我使用key1加密使用key2解密时,我期望会抛出一个CryptographicException,但它实际上是一个乱码。
class Program
{
private static readonly byte[] key1 = new byte[] { 0xAC, 0x1F, 0xC4, 0x8F, 0x4C, 0x79, 0x10, 0xA1, 0x11, 0xD6, 0x7D, 0x24, 0xCE, 0x73, 0x6C, 0xE7, 0x8E, 0xD2, 0x97, 0xC2, 0x90, 0x21, 0x27, 0xE9, 0x68, 0x3F, 0x50, 0x5B, 0x92, 0x40, 0x6D, 0xC9 };
private static readonly byte[] iv1 = new byte[] { 0xF8, 0x14, 0x77, 0xFE, 0xFC, 0x84, 0x8E, 0x66, 0x82, 0x58, 0x01, 0x6D, 0x43, 0x12, 0xD8, 0x6F };
private static readonly byte[] key2 = new byte[] { 0x9D, 0xD8, 0x77, 0x5D, 0xA4, 0x60, 0x14, 0xFE, 0x89, 0xB6, 0xAF, 0x40, 0x2B, 0xFE, 0xE5, 0xD2, 0x0B, 0xDF, 0x55, 0x26, 0x37, 0x77, 0x6F, 0x21, 0x9A, 0x27, 0xB4, 0xD7, 0x08, 0xEA, 0xC6, 0xB9 };
private static readonly byte[] iv2 = new byte[] { 0x4D, 0x24, 0x83, 0x94, 0x3D, 0x29, 0x86, 0x7F, 0x40, 0x3A, 0x4F, 0x87, 0x37, 0x0B, 0x11, 0x8E };
static void Main(string[] args)
{
var ticks = 637375909118731913;
string original = JsonConvert.SerializeObject(new DateTime(ticks, DateTimeKind.Utc));
using (RijndaelManaged myRijndael = new RijndaelManaged())
{
byte[] encrypted = EncryptStringToBytes(original, key1, iv1);
Console.WriteLine("Original: {0}", original);
string roundtrip = DecryptStringFromBytes(encrypted, key1, iv1);
Console.WriteLine("Round Trip: {0}", roundtrip);
try
{
string roundtrip2 = DecryptStringFromBytes(encrypted, key2, iv2);
Console.WriteLine("Round Trip2: {0}", roundtrip2);
}
catch (CryptographicException e)
{
Console.WriteLine("Round Trip2: Unable to decrypt, expected.");
}
}
}
static byte[] EncryptStringToBytes(string plainText, byte[] Key, byte[] IV)
{
byte[] encrypted;
using (RijndaelManaged rijAlg = new RijndaelManaged())
{
rijAlg.Key = Key;
rijAlg.IV = IV;
ICryptoTransform encryptor = rijAlg.CreateEncryptor(rijAlg.Key, rijAlg.IV);
using (MemoryStream msEncrypt = new MemoryStream())
{
using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
{
using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
{
swEncrypt.Write(plainText);
}
encrypted = msEncrypt.ToArray();
}
}
}
return encrypted;
}
static string DecryptStringFromBytes(byte[] cipherText, byte[] Key, byte[] IV)
{
string plaintext = null;
using (RijndaelManaged rijAlg = new RijndaelManaged())
{
rijAlg.Key = Key;
rijAlg.IV = IV;
ICryptoTransform decryptor = rijAlg.CreateDecryptor(rijAlg.Key, rijAlg.IV);
using (MemoryStream msDecrypt = new MemoryStream(cipherText))
{
using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
{
using (StreamReader srDecrypt = new StreamReader(csDecrypt))
{
plaintext = srDecrypt.ReadToEnd();
}
}
}
}
return plaintext;
}
}
输出:
Original: "2020-10-06T14:21:51.8731913Z"
Round Trip: "2020-10-06T14:21:51.8731913Z"
Round Trip2: 7cB?]?wV???DFI?|hgY?Q?&x
预期:
Original: "2020-10-06T14:21:51.8731913Z"
Round Trip: "2020-10-06T14:21:51.8731913Z"
Round Trip2: Unable to decrypt, expected.
如果我更改刻度值,这只发生在特定输入中
var ticks = 637375909118731914;
一切都按预期进行。
我犯了什么错误?
注意:
还有许多其他输入值可能会导致这种情况,从而导致我的应用程序出现意外错误。
【问题讨论】:
-
您(处理/寻找)的特定加密异常是由于填充错误造成的。不幸的是,检查填充是一个非常弱完整性检查 - 许多不正确的键将通过填充检查并产生垃圾。
-
我找了一些例子,它只是捕获了所有异常,但似乎并没有解决我的问题,有没有办法判断解密是否成功?
-
@LiTang 你可以在消息前添加一些文本,你可以在解密后查看
-
RijndaelManaged 似乎没有现成的方法来检查结果,看来我必须编写额外的代码来处理这个问题。
标签: c# encryption aes rijndaelmanaged