Как использовать 'System.Security.Cryptography.AesManaged' для шифрования байта []? - PullRequest
13 голосов
/ 09 июня 2009

В основном я хочу использовать System.Security.Cryptography.AesManaged (или лучший класс, если вы думаете, что он есть?), Чтобы взять один байтовый массив и создать другой зашифрованный байтовый массив, используя заданный симметричный ключ (я предполагаю, что я понадобится?).

Мне также понадобится способ отменить эту процедуру.

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

Спасибо

Ответы [ 5 ]

12 голосов
/ 09 июня 2009

РЕДАКТИРОВАТЬ: заметил редактирование eed3si9n ... Я согласен, симметричное шифрование - плохой выбор для паролей. Вместо этого используйте хэши (и , а не MD5). Вот очень полный пример .

Простой пример:

byte[] clear = GetCleartext();
HashAlgorithm sha2 = SHA256CryptoServiceProvider.Create();
byte[] hashed = sha2.ComputeHash(clear);

Чтобы проверить правильный пароль, вы должны выполнить те же вычисления с предоставленным паролем и сравнить результат с хешем, имеющимся в вашей базе данных.

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

11 голосов
/ 09 июня 2009

Вот что я сделал в конце, вдохновленный (более старой версией) ответа Майкла:

private string Encrypt(string input)
{
  return Convert.ToBase64String(Encrypt(Encoding.UTF8.GetBytes(input)));
}
private byte[] Encrypt(byte[] input)
{
  PasswordDeriveBytes pdb = new PasswordDeriveBytes("hjiweykaksd", new byte[] { 0x43, 0x87, 0x23, 0x72, 0x45, 0x56, 0x68, 0x14, 0x62, 0x84 });
  MemoryStream ms = new MemoryStream();
  Aes aes = new AesManaged();
  aes.Key = pdb.GetBytes(aes.KeySize / 8);
  aes.IV = pdb.GetBytes(aes.BlockSize / 8);
  CryptoStream cs = new CryptoStream(ms, aes.CreateEncryptor(), CryptoStreamMode.Write);
  cs.Write(input, 0, input.Length);
  cs.Close();
  return ms.ToArray();
}
private string Decrypt(string input)
{
  return Encoding.UTF8.GetString(Decrypt(Convert.FromBase64String(input)));
}
private byte[] Decrypt(byte[] input)
{
  PasswordDeriveBytes pdb = new PasswordDeriveBytes("hjiweykaksd", new byte[] { 0x43, 0x87, 0x23, 0x72, 0x45, 0x56, 0x68, 0x14, 0x62, 0x84 });
  MemoryStream ms = new MemoryStream();
  Aes aes = new AesManaged();
  aes.Key = pdb.GetBytes(aes.KeySize / 8);
  aes.IV = pdb.GetBytes(aes.BlockSize / 8);
  CryptoStream cs = new CryptoStream(ms, aes.CreateDecryptor(), CryptoStreamMode.Write);
  cs.Write(input, 0, input.Length);
  cs.Close();
  return ms.ToArray();
}
8 голосов
/ 09 июня 2009

Простое шифрование и дешифрование данных в C # .

Редактировать : Для паролей я бы рекомендовал использовать BCrypt вместо двустороннего шифрования, если только вам действительно не нужно восстановить исходный пароль. Обычно вам нужен только тот факт, что кто-то знает пароль, а не сам пароль.

2 голосов
/ 30 марта 2012

Существует довольно хорошая реализация C # симметричного ключа шифрования на http://www.superstarcoders.com/blogs/posts/symmetric-encryption-in-c-sharp.aspx. Он поддерживает AES, Triple DES и Rijndael. Он имеет простые функции в форме:

 string Encrypt(string plaintext, string password, string salt)
0 голосов
/ 14 июля 2016

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

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

Но давайте предположим, что вам нужно передать учетные данные через Basic Auth SSL / TLS. Так что теперь вам нужно надежно хранить их в обратимом виде. Чтобы решить эту проблему, я успешно использовал секретный ключ, передаваемый с использованием закрытого ключа сертификата. Это обеспечивает некоторую защиту вашего секрета операционной системой и позволяет пользователям OPS управлять ключами, что желательно. Учетной записи, используемой для запуска вашего процесса, должны быть предоставлены права на просмотр закрытого ключа, который затем завершает цепочку доверия в ОС.

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

Кроме того, SecureString может представлять интерес, но до тех пор, пока все .NET API не разрешат передачу SecureString в качестве части учетных данных, часто вы получаете строку в управляемой куче, которую вы не можете уничтожить.

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

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