Как создать ключ шифрования для алгоритмов шифрования? - PullRequest
29 голосов
/ 23 марта 2010

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

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

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

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

Ответы [ 6 ]

37 голосов
/ 25 марта 2010

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

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

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

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

14 голосов
/ 20 апреля 2010

Звучит так, будто вам нужно читать в класс 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 имеет размер ключа req ': 128Bits = 16 байт !!! (8 * 8 = 64, 64 бит / 8 бит на байт = 8 байтов) Поэтому

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

256Bit = 32Bytes !!!!


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


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

13 голосов
/ 23 марта 2010

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

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

Обновление

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

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

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

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

8 голосов
/ 23 марта 2010

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

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

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);
}
6 голосов
/ 23 марта 2010

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

var rnd = new System.Security.Cryptography.RandomNumberGenerator.Create();
var key = new byte[50];
rnd.GetBytes(key);
0 голосов
/ 23 марта 2010

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

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

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

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