2009-12-20 4 views
5

Я видел некоторый код, какКак RFC2898DeriveBytes генерирует ключ AES?

string password = "11111111"; 
byte[] salt = Encoding.ASCII.GetBytes("22222222"); 
Rfc2898DeriveBytes key = new Rfc2898DeriveBytes(password, salt); 
RijndaelAlg.Key = key.GetBytes(RijndaelAlg.KeySize/8); 

я вижу ключ генерируется Rfc2898DeriveBytes с ключевой фразой и солью. Затем AES извлекает ключ GetBytes.

Но вопрос в том, что делает RFC2898DeriveBytes и какой ключ.GetBytes (cb)? Может ли кто-нибудь это уточнить? Я не мог получить его из документации.

ответ

10

RFC2898 относится к основанной на паролях криптографической спецификации, опубликованной в сентябре 2000 года. Фактически, Rfc2898DeriveBytes принимает пароль и соль для генерации ключей. Используемый метод известен как PBKDF2 (функция деривации пароля на основе пароля № 2) и определен в разделе 5.2 RFC2898. Из раздела 5.2:

PBKDF2 применяет псевдослучайную функцию (см. Приложение B.1 для примера) для получения ключей. Длина производного ключа по существу неограничена. (Тем не менее, максимальное эффективное пространство поиска для производного ключа может быть ограничено структурой псевдослучайной функции. См. Приложение B.1 для дальнейшего обсуждения.) PBKDF2 рекомендуется для новых приложений.

Для получения дополнительной информации см. RFC2898.

Что касается Rfc2898DeriveBytes.GetBytes, он возвращает другой ключ для каждого вызова; он эффективно просто применяет PBKDF2 несколько раз с тем же паролем и солью, но также итерацией.

Это описано в RFC документ, где PBKDF2 определяется как

PBKDF2 (P, S, c, dkLen) 

где P это пароль, S это соль, c является счетчиком итераций и dkLen длина требуемого ключа.

RFCs в целом очень интересны и исторически весьма важны. RFC 1149 весьма важен, как и RFC 2324.

+0

возвращает другой ключ при каждом вызове Но я узнал, что ключи возвращаются все равно – Kelvin

+0

@Kelvin: Вы уверены, что вы используя его в том же экземпляре 'Rfc2898DeriveBytes'? Фактически невозможно увидеть те же байты, которые были возвращены при последовательных вызовах 'Rfc2898DeriveBytes.GetBytes' в том же экземпляре' Rfc2898DeriveBytes'. – jason

+0

RijndaelManaged RijndaelAlg = новый RijndaelManaged(); строка пароль = "11111111"; Rfc2898DeriveBytes key = new Rfc2898DeriveBytes (пароль, Encoding.ASCII.GetBytes ("22222222")); RijndaelAlg.Key = key.GetBytes (RijndaelAlg.KeySize/8); байт [] a = key.GetBytes (32); для (int i = 0; i Kelvin

4

Глядя на реализацию в Рефлектор:

public Rfc2898DeriveBytes(string password, byte[] salt) : this(password, salt, 0x3e8) 
{ 
} 

public Rfc2898DeriveBytes(string password, int saltSize, int iterations) 
{ 
    if (saltSize < 0) 
    { 
     throw new ArgumentOutOfRangeException("saltSize", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); 
    } 
    byte[] data = new byte[saltSize]; 
    Utils.StaticRandomNumberGenerator.GetBytes(data); 
    this.Salt = data; 
    this.IterationCount = iterations; 
    this.m_hmacsha1 = new HMACSHA1(new UTF8Encoding(false).GetBytes(password)); 
    this.Initialize(); 
} 


public override byte[] GetBytes(int cb) 
{ 
    if (cb <= 0) 
    { 
     throw new ArgumentOutOfRangeException("cb", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); 
    } 
    byte[] dst = new byte[cb]; 
    int dstOffset = 0; 
    int count = this.m_endIndex - this.m_startIndex; 
    if (count > 0) 
    { 
     if (cb < count) 
     { 
      Buffer.InternalBlockCopy(this.m_buffer, this.m_startIndex, dst, 0, cb); 
      this.m_startIndex += cb; 
      return dst; 
     } 
     Buffer.InternalBlockCopy(this.m_buffer, this.m_startIndex, dst, 0, count); 
     this.m_startIndex = this.m_endIndex = 0; 
     dstOffset += count; 
    } 
    while (dstOffset < cb) 
    { 
     byte[] src = this.Func(); 
     int num3 = cb - dstOffset; 
     if (num3 > 20) 
     { 
      Buffer.InternalBlockCopy(src, 0, dst, dstOffset, 20); 
      dstOffset += 20; 
     } 
     else 
     { 
      Buffer.InternalBlockCopy(src, 0, dst, dstOffset, num3); 
      dstOffset += num3; 
      Buffer.InternalBlockCopy(src, num3, this.m_buffer, this.m_startIndex, 20 - num3); 
      this.m_endIndex += 20 - num3; 
      return dst; 
     } 
    } 
    return dst; 
} 
+0

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

+0

Используйте что-то вроде http://ilspy.net/ и проверьте код самостоятельно :) Я использую Reflector, но должен быть тем же. –

+1

@ Phil_1984_ Вы можете найти источник ссылки на исходном сайте Microsoft, в данном случае [ссылка] (http://referencesource.microsoft.com/#mscorlib/system/security/cryptography/rfc2898derivebytes.cs) http: // sourcesource .microsoft.com/# mscorlib/system/security/cryptography/rfc2898derivebytes.cs. –

 Смежные вопросы

  • Нет связанных вопросов^_^