Перевести Rfc2898DeriveBytes в рубин - PullRequest
0 голосов
/ 14 января 2019

Я пытаюсь перевести криптоалгоритм из c # в ruby.

Первый шаг - создать ключ и iv с функцией деривации ключа:

    string myTestString = "my_test_string";

    Rfc2898DeriveBytes rfcDb = new Rfc2898DeriveBytes(myTestString, System.Text.Encoding.UTF8.GetBytes(myTestString));

    byte[] key = rfcDb.GetBytes(16);
    byte[] iv = rfcDb.GetBytes(16);

    Console.WriteLine("key => " + Convert.ToBase64String(key)); 
    Console.WriteLine("iv =>  " + Convert.ToBase64String(iv));

Выход:

key => rI9LR/UyZz5UuLQm1ujqDA==
iv =>  DDBRWmlgAdOxIkVhvgluRA==

В ruby ​​я использую гем PBKDF2 и пытаюсь получить те же значения:

    my_test_string = "my_test_string";
    rfc_db = PBKDF2.new(password: my_test_string, salt: my_test_string, iterations: 10000, hash_function: :sha1).bin_string

    key = rfc_db.bytes[0, 15].join
    iv = rfc_db.bytes[16, 32].join

    puts "key => " + Base64.encode64(key)
    puts "iv => " + Base64.encode64(iv)

Выход:

key => NjgxNzMxNjYxNDUyMDIxMjAxNjMxOTExOTEzMjYyMTYyMTQzMTkyMTc3
iv => OTIxODYxNzkxMjc=

Обновление в соответствии с ответом, однако результаты все еще различаются:

string myTestString = "my_test_string";

Rfc2898DeriveBytes rfcDb = new Rfc2898DeriveBytes(myTestString, System.Text.Encoding.UTF8.GetBytes(myTestString));

byte[] key = rfcDb.GetBytes(16);
byte[] iv = rfcDb.GetBytes(16);

Console.WriteLine("key => " + OutputBytesArray(key));   
Console.WriteLine("iv =>  " + OutputBytesArray(iv));    

Выход:

key => 172 143 75 71 245 50 103 62 84 184 180 38 214 232 234 12 
iv =>  12 48 81 90 105 96 1 211 177 34 69 97 190 9 110 68

А для кода Ruby:

my_test_string = "my_test_string";

rfc_db = PBKDF2.new(password: my_test_string, salt: my_test_string, iterations: 10000, hash_function: :sha1, key_length: 32).bin_string

key = rfc_db.bytes[0, 16]
iv = rfc_db.bytes[16, 16]

puts "key => " + key.inspect
puts "iv => " + iv.inspect

Вывод:

key => [68, 173, 166, 145, 202, 120, 163, 191, 191, 32, 62, 162, 143, 192, 177, 104]
iv => [92, 186, 179, 127, 42, 221, 74, 182, 148, 87, 217, 167, 109, 62, 54, 22]

Может кто-нибудь объяснить мне, что я делаю не так?

1 Ответ

0 голосов
/ 15 января 2019

Есть как минимум 3 - [править: сейчас 4] - ошибки в коде:

  • Наиболее важным и интересным для StackOverflow является то, что PBKDF2 определен в Ruby для вывода выходного размера хеш-функции в байтах, чтобы гарантировать, что она запускается только один раз. Однако SHA-1 выводит 160 бит, в то время как вы (пытаетесь) запросить 2 * 16 = 32 байта или 256 бит. Таким образом, ваш IV заканчивается бит.

  • Во-вторых, неправильная кодировка; join просто объединит десятичное значение байтов, которое кажется - я не понимаю, зачем это нужно вообще .

  • Когда вы смотрите, как Руби выполняет нарезку, кажется, что он использует ary[start, length]new_ary или nil.

  • Наконец, ваш код Ruby указывает 10000 (лучше записать как 10_000, чтобы избежать глупых ошибок, подобных этим) вместо 1000 в качестве счетчика итераций (неправильно определено и слишком низкое значение C # по умолчанию). Лучше обновить и указать количество итераций в коде C #.

Может потребоваться установить длину и вызвать .bytes только один раз для результата, а затем разделить ее после (поскольку байты кажутся различными, кажется, что реализация PKBDF2 достаточно умна для вычисления требуемый результат только один раз - лично мне не нравится зависеть от особенностей реализации, подобных этим).

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