2014-09-17 2 views
6

Я совершенно новый для криптографии, но обучения. Я собрал много разных предложений из моего исследования в Интернете и сделал свой собственный класс для обработки хеша, соли, растяжения клавиш и сравнения/преобразования связанных данных.Как использовать SHA-512 с Rfc2898DeriveBytes в моем солевом и хеш-коде?

После изучения встроенной библиотеки .NET для криптографии я обнаружил, что у меня есть только SHA-1. Но я прихожу к выводу, что это неплохо, так как я использую несколько итераций хэш-процесса. Это верно?

Но если бы я хотел начать с более надежного SHA-512, как я мог бы реализовать его в своем коде ниже? Заранее спасибо.

using System; 
using System.Runtime.InteropServices; 
using System.Security; 
using System.Security.Cryptography; 

public class CryptoSaltAndHash 
{ 
    private string strHash; 
    private string strSalt; 
    public const int SaltSizeInBytes = 128; 
    public const int HashSizeInBytes = 1024; 
    public const int Iterations = 3000; 

    public string Hash { get { return strHash; } } 
    public string Salt { get { return strSalt; } } 

    public CryptoSaltAndHash(SecureString ThisPassword) 
    { 
     byte[] bytesSalt = new byte[SaltSizeInBytes]; 
     using (RNGCryptoServiceProvider crypto = new RNGCryptoServiceProvider()) 
     { 
      crypto.GetBytes(bytesSalt); 
     } 
     strSalt = Convert.ToBase64String(bytesSalt); 
     strHash = ComputeHash(strSalt, ThisPassword); 
    } 

    public static string ComputeHash(string ThisSalt, SecureString ThisPassword) 
    { 
     byte[] bytesSalt = Convert.FromBase64String(ThisSalt); 
     Rfc2898DeriveBytes pbkdf2 = new Rfc2898DeriveBytes(
      convertSecureStringToString(ThisPassword), bytesSalt, Iterations); 
     using (pbkdf2) 
     { 
      return Convert.ToBase64String(pbkdf2.GetBytes(HashSizeInBytes)); 
     } 
    } 

    public static bool Verify(string ThisSalt, string ThisHash, SecureString ThisPassword) 
    { 
     if (slowEquals(getBytes(ThisHash), getBytes(ComputeHash(ThisSalt, ThisPassword)))) 
     { 
      return true; 
     } 
     return false; 
    } 

    private static string convertSecureStringToString(SecureString MySecureString) 
    { 
     IntPtr ptr = IntPtr.Zero; 
     try 
     { 
      ptr = Marshal.SecureStringToGlobalAllocUnicode(MySecureString); 
      return Marshal.PtrToStringUni(ptr); 
     } 
     finally 
     { 
      Marshal.ZeroFreeGlobalAllocUnicode(ptr); 
     } 
    } 

    private static bool slowEquals(byte[] A, byte[] B) 
    { 
     int intDiff = A.Length^B.Length; 
     for (int i = 0; i < A.Length && i < B.Length; i++) 
     { 
      intDiff |= A[i]^B[i]; 
     } 
     return intDiff == 0; 
    } 

    private static byte[] getBytes(string MyString) 
    { 
     byte[] b = new byte[MyString.Length * sizeof(char)]; 
     System.Buffer.BlockCopy(MyString.ToCharArray(), 0, b, 0, b.Length); 
     return b; 
    } 
} 

Примечание: Я ссылаюсь много практики из https://crackstation.net/hashing-security.htm. Метод сравнения slowEquals - это нормализовать время выполнения, предотвращая ветвление. Использование SecureString заключается в том, чтобы зашифрованная форма пароля проходила между этим классом и другими классами и страницами в моем веб-приложении. Хотя этот сайт будет зависеть от HTTPS, всегда приятно пройти лишнюю милю, чтобы обеспечить безопасность как можно безопаснее, пока все еще находится в пределах разумного.

В моем коде я установил ключевую строку на 128 байт (хотя иногда она увеличивается, а это нормально), размер хэша до 1 Кбайт и количество итераций в 3000. Это немного больше, чем типичная 64-байтовая соль, 512-байтовый хеш и 1000 или 2 000 итераций, но опять же скорость входа в систему и производительность приложения - чрезвычайно низкий приоритет.

Мысли?

+0

Аналогичный вопрос при проверке кода: [Безопасное шифрование пароля] (http://codereview.stackexchange.com/questions/32856/secure-password-hashing) – CodesInChaos

ответ

5

Отвечая на вопрос: Скачайте образцы свободного кода из «SecurityDriven.NET». Найти PBKDF2 класс, который принимает HMAC завод. HMACSHA512 завод, среди других.

Поскольку вы новичок в криптографии, я также настоятельно рекомендую вам прочитать книгу (например, чтобы полностью понять моменты, которые сделал CodesInChaos).

+0

Спасибо. Хотя эти примеры используют .NET 4.5, я нахожусь на .NET 4.0. Однако они должны работать как с минимальными изменениями. Эти примеры относятся к классу шифрования, который мне нужен: http://msdn.microsoft.com/en-us/library/system.security.cryptography.sha512%28v=vs.100%29.aspx –

8
  1. 3000 итераций довольно низкое. Даже 10000 является низким. Но вам нужно весить усиление безопасности дополнительных итераций против риска того, что злоумышленник выполнит DoS-сервер на вашем сервере, пытаясь войти в систему часто, что вызывает дорогостоящий хеш для каждой попытки.
  2. Нет смысла в соли размером более 128 бит/16 байт. Соль должна быть уникальной, не более того.
  3. Размер хэша больше собственного размера (20 байт для SHA-1) снижает эффективность для защитника, но не для злоумышленника. Поскольку это означает, что вы можете позволить меньше итераций, это фактически ослабляет безопасность.

    Например, при той же стоимости, что и ваш 1024-байтовый хеш с 3000 итерациями, вы можете позволить себе 20-байтовый хеш с 156000 итерациями, что в 52 раза дороже трещины.

  4. Для использования SHA-2 вам понадобится совершенно другая реализация PBKDF2, одна из которых включена в .net, жестко запрограммирована для использования SHA-1.

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

  5. Ваш API неудобен в использовании, поскольку вы нажимаете на управление солью на вызывающего абонента, а не обрабатываете его в пределах функций Create/Verify.

  6. Глупо использовать SecureString, а затем преобразовать его в String. Это в первую очередь противодействует всей точке использования SecureString.

    Лично я не стал бы беспокоиться о SecureString в типичном приложении.Это целесообразно, если вы объедините его с обширным обзором безопасности целого стека, который проверяет, что пароль никогда не хранится в String и всегда удаляется из изменяемого хранилища, как только он больше не требуется.

  7. Я бы не хранил пароли/соли в переменных экземпляра. Просто держите их локальными в соответствующих функциях. Я бы сохранил конфигурацию в переменных экземпляра (например, количество итераций).

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

    Главное преимущество SHA-512 заключается не в том, что он криптографически сильнее (хотя это и есть), это то, что 64-битная арифметика стоит атакующему больше, чем защитник, так как защитник, вероятно, будет использовать 64-битный процессор Intel, который быстро предлагает 64-битная арифметика.

+0

Отличный совет, большое вам спасибо! Я не забуду использовать SecureString, если я никогда не буду преобразовывать его в строку в коде. Что касается моего API, который неловко используется, он, похоже, работает нормально. Создайте экземпляр класса, чтобы создать соль, или указав его статически, чтобы проверить ранее созданный хеш. Никакой менеджмент не нажал на вызывающего абонента. Однако мой вопрос вращается вокруг вашего №4. Не могли бы вы подробнее рассказать об этом предложении и о том, как он будет реализован в среде .NET (например: выберите библиотеку SHA-2, которую вы порекомендовали). Еще раз спасибо! –

+0

Я никогда не беспокоился о том, чтобы взглянуть на реализации C# PBKDF2-HMAC-SHA-2, поэтому я действительно не знаю. Я предполагаю, что bouncycastle поддерживает его. Лично я бы предпочел оценить bcrypt.net и другие реализации bcrypt. – CodesInChaos

1

Если кто-либо встречает этот вопрос путем поиска, теперь Microsoft предоставляет Microsoft.AspNetCore.Cryptography.KeyDerivation пакет NuGet, который позволяет использовать PBKDF2 с SHA-256 и SHA-512 хеш-функциями. Документация доступна по адресу docs.microsoft.com.