我在使用AES加密和MAC验证的C#应用程序中遇到了加密和解密过程的问题。加密似乎工作正常,但当我试图解密数据时,我遇到了“MAC验证失败”。数据完整性受损”错误。
using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;
namespace HellsgateDeveloperManager
{
public static class EncryptionManager
{
private const string encryptionKey = "MyEncryptionKey";
public static byte[] EncryptWithIntegrity(string plaintext)
{
byte[] iv = GenerateRandomBytes(16);
byte[] plaintextBytes = Encoding.UTF8.GetBytes(plaintext);
// Calculate the MAC over the plaintext data
byte[] mac = CalculateMAC(plaintextBytes, encryptionKey);
using (Aes aesAlg = Aes.Create())
{
aesAlg.Key = Encoding.UTF8.GetBytes(encryptionKey);
aesAlg.IV = iv;
ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);
byte[] encryptedData;
using (MemoryStream msEncrypt = new MemoryStream())
{
using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
{
csEncrypt.Write(plaintextBytes, 0, plaintextBytes.Length);
}
encryptedData = msEncrypt.ToArray();
}
byte[] encryptedDataWithMAC = new byte[iv.Length + encryptedData.Length + mac.Length];
Buffer.BlockCopy(iv, 0, encryptedDataWithMAC, 0, iv.Length);
Buffer.BlockCopy(encryptedData, 0, encryptedDataWithMAC, iv.Length, encryptedData.Length);
Buffer.BlockCopy(mac, 0, encryptedDataWithMAC, iv.Length + encryptedData.Length, mac.Length);
return encryptedDataWithMAC;
}
}
public static string DecryptWithIntegrity(byte[] encryptedDataWithMAC)
{
int ivLength = 16;
int macLength = 32;
int expectedMinLength = ivLength + macLength;
if (encryptedDataWithMAC == null || encryptedDataWithMAC.Length < expectedMinLength)
{
throw new ArgumentException("Invalid encrypted data format.");
}
byte[] iv = new byte[ivLength];
byte[] encryptedData = new byte[encryptedDataWithMAC.Length - ivLength - macLength];
byte[] receivedMAC = new byte[macLength];
Buffer.BlockCopy(encryptedDataWithMAC, 0, iv, 0, iv.Length);
Buffer.BlockCopy(encryptedDataWithMAC, iv.Length, encryptedData, 0, encryptedData.Length);
Buffer.BlockCopy(encryptedDataWithMAC, iv.Length + encryptedData.Length, receivedMAC, 0, receivedMAC.Length);
byte[] calculatedMAC = CalculateMAC(encryptedData, encryptionKey);
if (!CompareMACs(receivedMAC, calculatedMAC))
{
throw new CryptographicException("MAC verification failed. Data integrity compromised.");
}
using (Aes aesAlg = Aes.Create())
{
aesAlg.Key = Encoding.UTF8.GetBytes(encryptionKey);
aesAlg.IV = iv;
ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);
using (MemoryStream msDecrypt = new MemoryStream(encryptedData))
{
using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
{
using (StreamReader srDecrypt = new StreamReader(csDecrypt))
{
return srDecrypt.ReadToEnd();
}
}
}
}
}
private static byte[] CalculateMAC(byte[] data, string key)
{
byte[] keyBytes = Encoding.UTF8.GetBytes(key);
using (HMACSHA256 hmac = new HMACSHA256(keyBytes))
{
return hmac.ComputeHash(data);
}
}
private static bool CompareMACs(byte[] mac1, byte[] mac2)
{
if (mac1.Length != mac2.Length)
{
return false;
}
for (int i = 0; i < mac1.Length; i++)
{
if (mac1[i] != mac2[i])
{
return false;
}
}
return true;
}
private static byte[] GenerateRandomBytes(int length)
{
byte[] randomBytes = new byte[length];
using (RandomNumberGenerator rng = RandomNumberGenerator.Create())
{
rng.GetBytes(randomBytes);
}
return randomBytes;
}
}
}
字符串
每当我尝试比较MAC时,就会出现错误。
我将非常感谢任何见解,建议或可能的解决方案,以帮助我解决这个问题。如果任何人在使用C# AES加密和MAC验证时遇到类似的问题,或者如果我可以采取任何其他故障排除步骤,请告诉我。提前感谢您的帮助!
为了调试这个问题,我仔细检查了加密代码,包括IV的生成和MAC。我还检查了加密和解密使用的密钥是否相同。我实施了大量的日志记录来跟踪过程中的数据和密钥,但我无法确定任何差异。我尝试使用Chat-gpt来获得一些指导,但没有进一步的帮助。
1条答案
按热度按时间hmtdttj41#
您正在计算加密明文的MAC,并且正在计算解密密文 * 的MAC *。最好转换为使用encrypt-then-mac。这基本上就是你在解密过程中所做的。如果你这样做,你应该确保将IV包括在计算中。
就目前而言,您应该知道发送相同的消息将导致加密期间相同的MAC,这意味着有关消息的少量信息将被泄露。更糟糕的是,在解密过程中,你可能容易受到填充oracle攻击。
还有其他安全问题,例如使用字符串来构成密钥,使用依赖于静态密钥的静态方法,用于认证标签(MAC结果)的非时间常数比较。也许你可以使用GCM来代替,这样大部分问题都可以很容易地解决。
即使这样,你也应该担心你的协议是否安全,是否容易受到例如重播攻击这就是为什么,你最好不要尝试创建自己的。