gpt4 book ai didi

c# - AES 加密 - 加密/解密添加额外字节

转载 作者:行者123 更新时间:2023-12-05 09:21:02 33 4
gpt4 key购买 nike

我正在使用框架的对象编写一个用于加密/解密的简单库。方法如下:

public static byte[] Encrypt(byte[] key, byte[] vector, byte[] input)
{
if(key.Length == 0)
throw new ArgumentException("Cannot encrypt with empty key");

if (vector.Length == 0)
throw new ArgumentException("Cannot encrypt with empty vector");

if (input.Length == 0)
throw new ArgumentException("Cannot encrypt empty input");

var unencryptedBytes = input;

using(AesCryptoServiceProvider aes = new AesCryptoServiceProvider {Key = key, IV = vector})
using(ICryptoTransform encryptor = aes.CreateEncryptor())
using (MemoryStream ms = new MemoryStream())
using (CryptoStream writer = new CryptoStream(ms, encryptor, CryptoStreamMode.Write))
{
writer.Write(unencryptedBytes, 0, unencryptedBytes.Length);
writer.FlushFinalBlock();
var byteArray = ms.ToArray();

if(byteArray.Length == 0)
throw new Exception("Attempted to encrypt but encryption resulted in a byte array of 0 length.");

return byteArray;
}
}


public static byte[] Decrypt(byte[] key, byte[] vector, byte[] encrypted)
{
if (key.Length == 0)
throw new ArgumentException("Cannot encrypt with empty key");

if (vector.Length == 0)
throw new ArgumentException("Cannot encrypt with empty vector");

if (encrypted == null || encrypted.Length == 0)
throw new ArgumentException("Cannot decrypt empty or null byte array");

byte[] unencrypted;

using (AesCryptoServiceProvider aes = new AesCryptoServiceProvider { Key = key, IV = vector })
using (ICryptoTransform decryptor = aes.CreateDecryptor(key, vector))
using (MemoryStream ms = new MemoryStream(encrypted))
using (CryptoStream cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Read))
{

cs.Read(encrypted, 0, encrypted.Length);

unencrypted = ms.ToArray();
}


return unencrypted;
}

将其放入编码字符串中,例如,如下所示:

var expected = "This is an example message";

var messageBytes = Encoding.UTF8.GetBytes(expected);

输入为(在本例中)26 个字节。加密后保留为 32 字节,当将其转换回字符串时,它在末尾附加了随机字符,但在其他方面完全有效,如下所示:

"This is an example message�(4���"

生成新的向量/ key 会更改附加到末尾的随机字符。

如何消除这种额外字节行为?

编辑

包括请求的单元测试。

[TestMethod]
public void CanEncryptAndDecryptByteArray()
{
var expected = "This is an example message";

var messageBytes = Encoding.UTF8.GetBytes(expected);


AesCryptoServiceProvider aes = new AesCryptoServiceProvider();
aes.GenerateIV();
aes.GenerateKey();


var byteKey = Convert.ToBase64String(aes.Key);
var vectorKey = Convert.ToBase64String(aes.IV);

var key = Convert.FromBase64String("Qcf+3VzYNAfPUCfBO/ePSxCLBLItkVfk8ajK86KYebs=");
var vector = Convert.FromBase64String("aJNKWP7M2D44jilby6BzGg==");

var encrypted = EncryptionManager.Encrypt(key, vector, messageBytes);
var decrypted = EncryptionManager.Decrypt(key, vector, encrypted);

var actual = Encoding.UTF8.GetString(decrypted);

Assert.AreEqual(expected, actual);
}

最佳答案

垃圾字节是因为我们正在读取和写入同一个数组。

new MemoryStream(encrypted)) 告诉 crypt 从 encrypted 中读取。

cs.Read(encrypted, 0, encrypted.Length); 告诉它写入 encrypted

解决方法:

using (AesCryptoServiceProvider aes = new AesCryptoServiceProvider { Key = key, IV = vector })
using (ICryptoTransform decryptor = aes.CreateDecryptor(key, vector))
using (MemoryStream ms = new MemoryStream(encrypted))
using (CryptoStream cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Read))
{
var decrypted = new byte[encrypted.Length];
var bytesRead = cs.Read(decrypted, 0, encrypted.Length);

return decrypted.Take(bytesRead).ToArray();
}

请注意,我们从数组中获取 bytesRead,而不是整个数组,否则我们将以空字节结束(字符串比较失败但在编辑器中显示相同)

关于c# - AES 加密 - 加密/解密添加额外字节,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35029499/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com