需要有关加密/解密问题的帮助。
我需要加密 GUID 字符串并将其保存到数据库,然后将其解密并用于识别数据。
但是,加密的字符串有时能够解密,有时则不能。看起来我的代码中缺少一些东西:
public string Encrypt(string stringToEncrypt, string sEncryptionKey)
{
byte[] key = Encoding.UTF8.GetBytes(sEncryptionKey.PadLeft(32));
byte[] inputByteArray = Encoding.UTF8.GetBytes(stringToEncrypt);
byte[] encrypted;
using (Aes aes = Aes.Create())
{
ICryptoTransform encryptor = aes.CreateEncryptor(key, IV);
using MemoryStream msEncrypt = new();
using CryptoStream csEncrypt = new(msEncrypt, encryptor, CryptoStreamMode.Write);
csEncrypt.Write(inputByteArray, 0, inputByteArray.Length);
csEncrypt.FlushFinalBlock();
encrypted = msEncrypt.ToArray();
}
return HttpUtility.UrlEncode(Convert.ToBase64String(encrypted));
}
public string Decrypt(string stringToDecrypt, string sEncryptionKey)
{
string result = string.Empty;
byte[] key = Encoding.UTF8.GetBytes(sEncryptionKey.PadLeft(32));
byte[] inputByteArray = Convert.FromBase64String(HttpUtility.UrlDecode(stringToDecrypt));
Encoding encoding = Encoding.UTF8;
using (Aes aes = Aes.Create())
{
ICryptoTransform decryptor = aes.CreateDecryptor(key, IV);
using MemoryStream msDecrypt = new();
using CryptoStream csDecrypt = new(msDecrypt, decryptor, CryptoStreamMode.Write);
csDecrypt.Write(inputByteArray, 0, inputByteArray.Length);
csDecrypt.FlushFinalBlock();
result = encoding.GetString(msDecrypt.ToArray());
}
return result;
}
两个函数都使用相同的 IV 和加密密钥,并且我已经使用这些加密字符串测试了我的代码
不知何故,尽管使用相同的加密功能,但只有第一个不起作用。异常发生在解密方法的 FlushFinalBlock() 行上。
加密是在.NET 6应用程序中完成的
解密在.NET 4.6.1应用程序中完成
这是要测试的示例密钥和 IV:
键 = d4n40nly
IV = 新字节[] { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F };
有人可以启发我吗?
尝试这样:
using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;
public class Program
{
private static byte[] IV = new byte[] { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F };
private static string key = "d4n40nly";
public static string Encrypt(string plainText, string strKey)
{
byte[] bytesKey = Encoding.UTF8.GetBytes(strKey.PadLeft(32));
byte[] bytesPlainText = Encoding.UTF8.GetBytes(plainText);
byte[] bytesEncrypted;
// Create an Aes object with the specified padding, key and IV.
using (Aes aes = Aes.Create())
{
aes.Padding = PaddingMode.PKCS7;
aes.BlockSize = 128; // 16 bytes = 128 bit
aes.Key = bytesKey; // 32 bytes = 256 bit
aes.IV = IV; // 16 bytes = 128 bit
// Create an encryptor to perform the stream transform.
ICryptoTransform encryptor = aes.CreateEncryptor(aes.Key, aes.IV);
// Create the streams used for encryption.
using (MemoryStream msEncrypt = new MemoryStream())
{
using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
{
using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
{
//Write all data to the stream.
swEncrypt.Write(plainText);
}
bytesEncrypted = msEncrypt.ToArray();
}
}
}
return Convert.ToBase64String(bytesEncrypted);
}
public static string Decrypt(string cipherText, string strKey)
{
byte[] bytesKey = Encoding.UTF8.GetBytes(strKey.PadLeft(32));
byte[] bytesCipherText = Convert.FromBase64String(cipherText);
string plaintext = string.Empty;
// Create an Aes object with the specified padding, key and IV.
using (Aes aes = Aes.Create())
{
aes.Padding = PaddingMode.PKCS7;
aes.BlockSize = 128; // 16 bytes = 128 bit
aes.Key = bytesKey; // 32 bytes = 256 bit
aes.IV = IV; // 16 bytes = 128 bit
// Create a decryptor to perform the stream transform.
ICryptoTransform decryptor = aes.CreateDecryptor(aes.Key, aes.IV);
// Create the streams used for decryption.
using (MemoryStream msDecrypt = new MemoryStream(bytesCipherText))
{
using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
{
using (StreamReader srDecrypt = new StreamReader(csDecrypt))
{
// Read the decrypted bytes from the decrypting stream
plaintext = srDecrypt.ReadToEnd();
}
}
}
}
return plaintext;
}
public static void Main()
{
//for(int i=0; i<nt.MaxValue; i++) {
string plainText = Guid.NewGuid().ToString();
Console.WriteLine("plaintext: " + plainText);
string strEncrypted = Encrypt(plainText, key);
Console.WriteLine("encrypted: " + strEncrypted);
string strDecrypted = Decrypt(strEncrypted, key);
Console.WriteLine("decrypted: " + strDecrypted);
if(plainText.Equals(strDecrypted)){
Console.WriteLine("passed\n");
}
else {
Console.WriteLine("failed!\n\n");
//break;
}
//}
}
}
输出:
plaintext: b50cc962-59be-4c82-a846-117fbc3011dd
encrypted: Oco7yFjxWP4UD1OYRInzM3ukRByATBWOiWRPqrRyNYRoQdf0VfRUvptL3L3xUiq5
decrypted: b50cc962-59be-4c82-a846-117fbc3011dd
passed
我用random Guid进行测试,直到循环int.MaxValue-1,结果所有测试都成功。