gpt4 book ai didi

.net - .NET AES/Rijndael-重用解密器时解密不一致

转载 作者:行者123 更新时间:2023-12-01 13:38:44 26 4
gpt4 key购买 nike

我创建了一个使用AES进行加密和解密的类。

public class AesEncryptionProvider {
#region Fields

// Encryption key
private static readonly byte[] s_key = new byte[32] {
// Omitted...
};

// Initialization vector
private static readonly byte[] s_iv = new byte[16] {
// Omitted...
};

private AesCryptoServiceProvider m_provider;
private ICryptoTransform m_encryptor;
private ICryptoTransform m_decryptor;

#endregion

#region Constructors

private AesEncryptionProvider () {
m_provider = new AesCryptoServiceProvider();
m_encryptor = m_provider.CreateEncryptor(s_key, s_iv);
m_decryptor = m_provider.CreateDecryptor(s_key, s_iv);
}

static AesEncryptionProvider () {
Instance = new AesEncryptionProvider();
}

#endregion

#region Properties

public static AesEncryptionProvider Instance { get; private set; }

#endregion

#region Methods

public string Encrypt (string value) {
if (string.IsNullOrEmpty(value)) {
throw new ArgumentException("Value required.");
}

return Convert.ToBase64String(
Transform(
Encoding.UTF8.GetBytes(value),
m_encryptor));
}

public string Decrypt (string value) {
if (string.IsNullOrEmpty(value)) {
throw new ArgumentException("Value required.");
}

return Encoding.UTF8.GetString(
Transform(
Convert.FromBase64String(value),
m_decryptor));
}

#endregion

#region Private methods

private byte[] Transform (byte[] input, ICryptoTransform transform) {
byte[] output;
using (MemoryStream memory = new MemoryStream()) {
using (CryptoStream crypto = new CryptoStream(
memory,
transform,
CryptoStreamMode.Write
)) {
crypto.Write(input, 0, input.Length);
crypto.FlushFinalBlock();

output = memory.ToArray();
}
}
return output;
}

#endregion
}

如您所见,在两种情况下,我都是通过 MemoryStream写入 CryptoStream的。如果我在每次调用 m_provider.CreateDecyptor(s_key, s_iv)时都通过 Decrypt创建一个新的解密程序,则可以正常工作。

这里出了什么问题?为什么解密器的行为好像忘记了IV?调用 StreamReader.ReadToEnd()是否正在执行某些操作,以帮助 m_decryptor正常运行?

我想避免在此列出的两种“可行”方法中的任何一种,因为这两种方法都会影响性能,这是一条非常关键的路径。提前致谢。

最佳答案

好的,我承认我不知道为什么会这样,但是将AesCryptoServiceProvider更改为AesManaged和voila。

我还建议使您的类实现IDisposable,因为它包含实现它的三个成员变量。参见下面的代码更改:

public sealed class AesEncryptionProvider : IDisposable
{
// Encryption key
private static readonly byte[] key = new byte[]
{
// Omitted...
};

// Initialization vector
private static readonly byte[] iv = new byte[]
{
// Omitted...
};

private static readonly AesEncryptionProvider instance = new AesEncryptionProvider();

private readonly AesManaged provider;

private readonly ICryptoTransform encryptor;

private readonly ICryptoTransform decryptor;

private AesEncryptionProvider()
{
this.provider = new AesManaged();
this.encryptor = this.provider.CreateEncryptor(key, iv);
this.decryptor = this.provider.CreateDecryptor(key, iv);
}

public static AesEncryptionProvider Instance
{
get
{
return instance;
}
}

public void Dispose()
{
this.decryptor.Dispose();
this.encryptor.Dispose();
this.provider.Dispose();
GC.SuppressFinalize(this);
}

public string Encrypt(string value)
{
if (string.IsNullOrEmpty(value))
{
throw new ArgumentException("Value required.");
}

return Convert.ToBase64String(Transform(Encoding.UTF8.GetBytes(value), this.encryptor));
}

public string Decrypt(string value)
{
if (string.IsNullOrEmpty(value))
{
throw new ArgumentException("Value required.");
}

return Encoding.UTF8.GetString(Transform(Convert.FromBase64String(value), this.decryptor));
}

private static byte[] Transform(byte[] input, ICryptoTransform transform)
{
using (var memory = new MemoryStream())
using (var crypto = new CryptoStream(memory, transform, CryptoStreamMode.Write))
{
crypto.Write(input, 0, input.Length);
crypto.FlushFinalBlock();
return memory.ToArray();
}
}
}

关于.net - .NET AES/Rijndael-重用解密器时解密不一致,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3366811/

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