Как создать Ключ шифрования для Алгоритмов шифрования?

Я хочу использовать алгоритм шифрования, доступный в пространстве имен безопасности .NET, однако я пытаюсь понять, как генерировать ключ, например, для алгоритма AES нужны 256 битов, тот 16-байтовый ключ и некоторый вектор инициализации, который является также немногими байтами.

  1. Я могу использовать какую-либо комбинацию значений в моем Ключе и IV? например, все нули в Ключе и IV допустимы или нет? Я знаю деталь алгоритма, который делает много xors, так нулевая подача привычки польза, но является там какими-либо ограничениями этими алгоритмами?

  2. Или я должен генерировать ключ с помощью некоторой программы и сохранить его постоянно где-нибудь?

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

32
задан Akash Kava 23 March 2010 в 20:48
поделиться

6 ответов

Если вы используете шифрование для обмена данными, вам понадобится протокол обмена ключами, но вы не делаете его самостоятельно, вместо этого используйте другой полка как TLS или SSL.

Если вы используете шифрование для хранения данных, вы генерируете IV с помощью CryptGenRandom (или его эквивалента в .net RandomNumberGenerator.GetBytes ) и сохраняете его вместе с документом (ясно, нет нужно защищать IV). Вы никогда не записываете ключ, ключ предоставляется пользователем. Обычно ключ получается из парольной фразы с помощью CryptDeriveKey или его эквивалента в .Net PasswordDeriveKey.CryptDeriveKey .

Обновление

Чтобы сохранить секрет в базе данных, доступной только пользователю и администратору, вам необходимо использовать 3 ключа:

  • один для шифрования данных (назовите его ключом DK)
  • один пользовательский ключ для шифрования ключа DK (назовите его UK)
  • один ключ администратора для шифрования ключа DK (назовите его AK)

Теоретически вы шифруете данные с помощью DK, а затем шифруете DK с помощью UK и сохраняете их , зашифруйте DK с помощью AK и сохраните его. Таким образом, пользователь может снова использовать UK для дешифрования DK, а затем дешифровать данные, а администратор может использовать AK для дешифрования DK, а затем дешифровать данные. Большая проблема заключается в том, что система всегда автоматизирована, поэтому системе необходим доступ к ключу администратора, что означает, что это не настоящий ключ администратора, а системный ключ (он не может использоваться для целей, не связанных с например, отказ от авторства).

Напомним, что знание того, что такое IV или как использовать AES из C # и как работает алгоритм криптографии, даст вам ровно 0 (ноль) усилий при решении такого рода проблем. Проблема никогда не в том, какой IV и какой ключ использовать, проблема всегда в предоставлении ключей. Для реальных криптографических операций просто используйте встроенную поддержку из базы данных, см. Криптография в SQL Server . Я легко могу утверждать, что единственное средство , которое вам нужно, - это TDE ( Прозрачное шифрование данных ) для защиты от случайной потери носителя.

15
ответ дан 27 November 2019 в 20:08
поделиться

Вы действительно должны сделать это правильно :)

1) Используйте надежно сгенерированный случайный IV
2) Используйте надежно сгенерированный случайный ключ
3) Не используйте режим ECB - НИКОГДА

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

Приведенный выше код правильно и безопасно сгенерирует для вас случайный IV и случайный ключ.

39
ответ дан 27 November 2019 в 20:08
поделиться

Используйте System.Security.Cryptography.RandomNumberGenerator для генерации случайных байтов:

var rnd = new System.Security.Cryptography.RandomNumberGenerator.Create();
var key = new byte[50];
rnd.GetBytes(key);
6
ответ дан 27 November 2019 в 20:08
поделиться

Сгенерировать случайные буквы / шестнадцатеричный код определенной длины.

Эта функция (взятая из здесь ) возвращает случайный ключ определенной длины:

private static string CreateSalt(int size)
{
    //Generate a cryptographic random number.
    RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
    byte[] buff = new byte[size];
    rng.GetBytes(buff);

    // Return a Base64 string representation of the random number.
    return Convert.ToBase64String(buff);
}
9
ответ дан 27 November 2019 в 20:08
поделиться

Это действительно зависит от того, что вам нужно делать с ключом.

Если ключ должен быть сгенерирован компьютером (и может быть любым случайным значением), я обычно беру SHA256 из пары GUID. Это примерно такая же случайность, как и без аппаратного генератора случайных чисел.

Вы можете использовать ключи со всеми нулями, но, очевидно, это будет не очень безопасно.

0
ответ дан 27 November 2019 в 20:08
поделиться

Похоже, вам нужно прочитать класс Rfc2898DeriveBytes.

Rfc2898DeriveBytes.GetBytes();

В нем есть метод (см. Выше), который позволяет вам настраивать размер байтовых массивов, которые вводятся в свойства .Key и .IV по симметричному алгоритму шифрования, просто путем ввода значения типа int. Официальная книга MS 70-536 предлагает сделать это программно, разделив свойство KeySize / 8.

То есть TripleDes или AESManaged.Что бы вы ни использовали, у самого алгоритма будут некоторые предварительные требования, которые необходимо выполнить в первую очередь. Т.е. выполнение условий размера ключа. RunTime автоматически заполнит свойства, поля и т. Д. Лучшими и самыми сильными значениями для вас. Но IV и ключ должны исходить от вас. Вот как вы можете сделать следующее:

RijndaelManaged myAlg = new RiRijndaelManaged();
byte[] salt = Encoding.ASCII.GetBytes("Some salt value");
Rfc2898DeriveBytes key = new Rfc2898DeriveBytes("some password", salt);
myAlg.Key = key.GetBytes( myAlg.KeySize / 8);
myAlg.IV  = key.GetBytes( myAlg.BlockSize / 8);
// myAld should now fully set-up.

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

В книге Microsoft 70-536 говорится, что свойства .Key ожидают массивы байтов, которые вы передаете им в байтах, а не в битах. Класс RFC работает в байтах, тогда как свойство KeySize алгоритмов работает в битах. 1 байт = 8 бит. Вы видите, к чему это идет ...? Это должно дать вам представление о том, почему приведенный выше фрагмент кода выполнен именно так! Я изучил это, и для меня это чертовски разумно!

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

OBTW:

AESManaged имеет требуемый размер ключа: 128 бит = 16 байт !!! (8 * 8 = 64, 64 бит / 8 бит на байт = 8 байтов) Следовательно

64 * 2 = 128 бит, 8 * 2, ==> размер ключа 16 байтов!

256Bit = 32Bytes !!!!


Согласно официальному учебнику 70-536, Aes ограничен размером ключа 128 бит. Например, с классом Rijndael можно использовать 256 бит, 192 и 128 ключей.


Вы можете, с другой стороны, полностью забыть обо всей этой чуши и просто использовать вместо них методы .GenerateKey и GenerateIV, чтобы избавить вас от лишних хлопот, связанных с сортировкой заранее согласованного и согласованного пароля и статических значений соли. Ваша единственная забота - выяснить способ хранения и извлечения массивов ключей и байтов IV. Двоичный форматтер? .

14
ответ дан 27 November 2019 в 20:08
поделиться