我正在尝试从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
有人可以向我解释我在做什么错吗?
答案 0 :(得分:2)
至少有3个-[编辑:现在4个]-代码中的错误:
对于StackOverflow而言,最重要和有趣的是,在Ruby中定义了PBKDF2,以字节为单位输出哈希函数的输出大小,以确保其仅运行一次。但是,当您(尝试)要求2 * 16 = 32字节或256位时,SHA-1输出160位。因此,您的IV用完了。
第二,编码错误; join
会简单地将看上去的字节的十进制值连接起来-我根本不明白为什么需要
在查找Ruby的切片方式时,似乎使用了ary[start, length]
→new_ary
或nil
。
最后,您的Ruby代码指定10000
(最好写成10_000
以避免此类愚蠢的错误)而不是1000作为迭代计数(定义不正确且C#默认值太低) 。更好地更新并在C#代码中也指示迭代计数。
可能需要设置长度并仅对结果调用.bytes
一次,然后在之后将其拆分(因为字节似乎不同,因此PKBDF2实现似乎很聪明足以仅计算一次所需的结果-就我个人而言,我不希望依赖于诸如此类的实现细节。