哪种更快的方法来加密/解密c#中的数据?

时间:2018-07-06 10:28:09

标签: c# encryption

我使用了以下功能,但是它需要50秒到1分钟的时间才能解密1100条与我们联系的记录。因此,过滤某物大约需要1分钟的时间。因为我需要加密整个数据,所以我在C#中触发了过滤器查询。

这是Encrypt方法:

public static string Encrypt(string encryptString)
{
    if (string.IsNullOrEmpty(encryptString))
        return encryptString;

    string EncryptionKey = "---";
    byte[] clearBytes = Encoding.Unicode.GetBytes(encryptString);
    using (Aes encryptor = Aes.Create())
    {
        Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(EncryptionKey, new byte[] 
        { 
            0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 
        });

        encryptor.Key = pdb.GetBytes(32);
        encryptor.IV = pdb.GetBytes(16);

        using (MemoryStream ms = new MemoryStream())
        {
            using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateEncryptor(), CryptoStreamMode.Write))
            {
                cs.Write(clearBytes, 0, clearBytes.Length);
                cs.Close();
            }
            encryptString = Convert.ToBase64String(ms.ToArray());
        }
    }
    return encryptString;
}

这是我的Decrypt方法:

public static string Decrypt(string cipherText)
{
    if (string.IsNullOrEmpty(cipherText))
        return cipherText;

    string EncryptionKey = "---";
    cipherText = cipherText.Replace(" ", "+");
    byte[] cipherBytes = Convert.FromBase64String(cipherText);

    using (Aes encryptor = Aes.Create())
    {
        Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(EncryptionKey, new byte[] 
        {
            0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76
        });

        encryptor.Key = pdb.GetBytes(32);
        encryptor.IV = pdb.GetBytes(16);

        using (MemoryStream ms = new MemoryStream())
        {
            using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateDecryptor(), CryptoStreamMode.Write))
            {
                cs.Write(cipherBytes, 0, cipherBytes.Length);
                cs.Close();
            }
            cipherText = Encoding.Unicode.GetString(ms.ToArray());
        }
    }
    return cipherText;
}

2 个答案:

答案 0 :(得分:1)

您可以从接触点上方的回路中移除PBKDF2。如果您继续使用PBKDF2(由难以置信的Rfc2898DeriveBytes类实现的算法),则只需索取16个字节,即可获得3倍的免费加速,对安全性没有明显影响。然后,您可以使用由零字节组成的IV。

请注意,盐应该是随机的。当前,您可能会泄漏明文信息:如果两个加密消息的前几个块相同,那么攻击者将立即从密文中看到这一点。

我强烈建议您重新使用加密方案,如果可能的话,请聘请专家。 PBKDF2的输出不应直接用于加密数据库中的联系人。

答案 1 :(得分:1)

重构代码,解密和加密1000个项目只需不到一秒钟的时间。

var watch = new Stopwatch();
watch.Start();
using (var service = new Cryptography("---"))
{
    var listEncrypt = new List<string>();
    var listPlain = new List<string>();
    for (int i = 0; i < 1000; i++)
    {
        var encypt = service.Encrypt(i.ToString());
        listEncrypt.Add(encypt);
    }

    for (int i = 0; i < 1000; i++)
    {
        var plain = service.Decrypt(listEncrypt[i]);
        listPlain.Add(plain);
    }
}
watch.Stop();
Console.WriteLine(watch.Elapsed.Milliseconds.ToString());
Console.Read();

这个想法是只创建一个加密器实例来加密/解密列表

public class Cryptography : IDisposable
{
    private Aes Encryptor;

    public Cryptography(string key)
    {
        Encryptor = Aes.Create();
        var pdb = new Rfc2898DeriveBytes(key, new byte[]
            {
                0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76
            });

        Encryptor.Key = pdb.GetBytes(32);
        Encryptor.IV = pdb.GetBytes(16);
    }

    public string Encrypt(string plainText)
    {
        if (string.IsNullOrEmpty(plainText))
            return plainText;

        var clearBytes = Encoding.Unicode.GetBytes(plainText);

        using (var ms = new MemoryStream())
        {
            using (var cs = new CryptoStream(ms, Encryptor.CreateEncryptor(), CryptoStreamMode.Write))
            {
                cs.Write(clearBytes, 0, clearBytes.Length);
            }
            plainText = Convert.ToBase64String(ms.ToArray());
        }

        return plainText;
    }

    public string Decrypt(string cipherText)
    {
        if (string.IsNullOrEmpty(cipherText))
            return cipherText;

        cipherText = cipherText.Replace(" ", "+");
        var cipherBytes = Convert.FromBase64String(cipherText);

        using (var ms = new MemoryStream())
        {
            using (var cs = new CryptoStream(ms, Encryptor.CreateDecryptor(), CryptoStreamMode.Write))
            {
                cs.Write(cipherBytes, 0, cipherBytes.Length);
            }
            cipherText = Encoding.Unicode.GetString(ms.ToArray());
        }
        return cipherText;
    }

    public void Dispose()
    {
        Encryptor.Dispose();
    }
}