The methods of encryption and decryption come from Microsoft documentation.
I have two different sets of keys. When I use key1 to encrypt and use key2 to decrypt, I expect a CryptographicException to be thrown, but it is actually a garbled text.
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;
}
}
Output:
Original: "2020-10-06T14:21:51.8731913Z"
Round Trip: "2020-10-06T14:21:51.8731913Z"
Round Trip2: 7cB?]?wV???DFI?|hgY?Q?&x
Expect:
Original: "2020-10-06T14:21:51.8731913Z"
Round Trip: "2020-10-06T14:21:51.8731913Z"
Round Trip2: Unable to decrypt, expected.
This happens only in specific input, if I change the ticks value
var ticks = 637375909118731914;
Everything works as expected.
What mistake did i make?
Note:
There are many other input values that can cause this situation, which caused unexpected errors in my application.
My solution is to determine whether the string is in json format.
if(IsJson(roundtrip))
{
Console.WriteLine("Round Trip: {0}", roundtrip);
}
else
{
Console.WriteLine("Round Trip: Unable to decrypt.");
}