Какой более быстрый способ шифрования / дешифрования данных в C #? - PullRequest
0 голосов
/ 06 июля 2018

Я использовал следующую функцию, но расшифровка 1100 записей формы обратной связи заняла от 50 секунд до 1 минуты.Так что это займет около 1 минуты времени, когда я что-то фильтрую.Поскольку мне нужно зашифровать целые данные, я запускаю запрос фильтра в C #.

Это метод шифрования:

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;
}

А это мой метод расшифровки:

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 голосов
/ 07 июля 2018

Выполните рефакторинг вашего кода, и для расшифровки и шифрования 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();
    }
}
0 голосов
/ 07 июля 2018

Вы можете удалить PBKDF2 из контура, который проходит по контактам. Если вы продолжаете использовать PBKDF2 (алгоритм, реализованный классом с невероятно глупым именем Rfc2898DeriveBytes), просто попросите 16 байтов, и вы получите бесплатное ускорение в 3 раза, без каких-либо явных последствий для безопасности. Затем вы можете использовать IV, состоящий из нулевых байтов.

Обратите внимание, что ваша соль должна быть случайной. В настоящее время вы можете пропустить информацию в виде открытого текста: если первые несколько блоков двух зашифрованных сообщений идентичны, то злоумышленник сразу увидит это из зашифрованного текста.

Я настоятельно рекомендую вам пересмотреть схему шифрования и, если возможно, нанять эксперта. Вывод PBKDF2 не должен использоваться напрямую для шифрования контактов в базе данных.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...