Как использовать "System.Security.Cryptography.AesManaged" для шифрования байта []?

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

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

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

Спасибо

Ответ 1

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

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

Ответ 2

EDIT: Noted eed3si9n edit... Согласен, симметричное шифрование - плохой выбор для паролей. Вместо этого используйте хеши (и не MD5). Здесь очень полный пример.

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

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

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

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

Ответ 3

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

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

Ответ 4

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

 string Encrypt(string plaintext, string password, string salt)

Ответ 5

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

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

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

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

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

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