3

我创建了一个使用 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
}

如您所见,在这两种情况下,我都是通过 a写信给 a的。如果我在每次调用时创建一个新的解密器就可以了。MemoryStreamCryptoStreamm_provider.CreateDecyptor(s_key, s_iv)Decrypt

这里出了什么问题?为什么解密器表现得好像忘记了 IV?调用StreamReader.ReadToEnd()是否有助于m_decryptor正常运行?

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

4

1 回答 1

1

好的,我承认我不知道为什么会这样,但是更改AesCryptoServiceProviderAesManaged瞧瞧。

我还建议让你的类实现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();
        }
    }
}
于 2010-07-29T22:31:09.743 回答