在Ruby中翻译Rfc2898DeriveBytes

时间:2019-01-14 16:11:34

标签: c# .net ruby cryptography

我正在尝试从ruby中的c#转换加密算法。

第一步是创建具有密钥派生功能的密钥和iv:

Params.WndParent := 0

输出:

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

在红宝石中,我使用PBKDF2宝石并尝试产生相同的值:

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

输出:

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

对于Ruby代码:

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

输出:

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

有人可以向我解释我在做什么错吗?

1 个答案:

答案 0 :(得分:2)

至少有3个-[编辑:现在4个]-代码中的错误:

  • 对于StackOverflow而言,最重要和有趣的是,在Ruby中定义了PBKDF2,以字节为单位输出哈希函数的输出大小,以确保其仅运行一次。但是,当您(尝试)要求2 * 16 = 32字节或256位时,SHA-1输出160位。因此,您的IV用完了。

  • 第二,编码错误; join会简单地将看上去的字节的十进制值连接起来-我根本不明白为什么需要

  • 在查找Ruby的切片方式时,似乎使用了ary[start, length]new_arynil

  • 最后,您的Ruby代码指定10000(最好写成10_000以避免此类愚蠢的错误)而不是1000作为迭代计数(定义不正确且C#默认值太低) 。更好地更新并在C#代码中也指示迭代计数。

可能需要设置长度并仅对结果调用.bytes一次,然后在之后将其拆分(因为字节似乎不同,因此PKBDF2实现似乎很聪明足以仅计算一次所需的结果-就我个人而言,我不希望依赖于诸如此类的实现细节。