[英]Convert C# SHA256 hash to Ruby
我有C#代碼:
byte[] bytes = new UnicodeEncoding().GetBytes(input);
return Convert.ToBase64String(new SHA256Managed().ComputeHash(bytes));
將字符串編碼為SHA2哈希值,然后進行base 64編碼。 我需要將其轉換為Ruby。
我嘗試了幾種方法。 這是其中之一:
hash = Digest::SHA256.digest(val.encode('utf-8'))
encoded = Base64.urlsafe_encode64(hash)
我的代碼都產生了不匹配的相同結果。 我無法讓他們工作。 任何有關轉換這方面的幫助將不勝感激。
經過一些麻煩,我能夠使用硬編碼數組,問題是C#代碼在數組中的每個元素之后添加0。 這是工作的ruby代碼(帶有硬編碼數組):
Digest::SHA256.base64digest([99,0,104,0,97,0,100,0].pack('C*').force_encoding('utf-16'))
我想我可以遍歷數組,但這似乎沒必要。
解:
您需要使用UTF-16LE
編碼來獲得相同的SHA-256哈希
p hash = Digest::SHA256.base64digest("Hello".encode('UTF-16LE'))
我怎么找到的?
我使用在線C#工具使用以下代碼創建字符串"Hello"
的哈希值:
using System.IO;
using System;
using System.Text;
using System.Security.Cryptography;
class Program
{
static void Main()
{
byte[] bytes = new UnicodeEncoding().GetBytes("Hello");
String s = Convert.ToBase64String(new SHA256Managed().ComputeHash(bytes));
Console.WriteLine(s);
}
}
上面的程序產生了輸出oH5Pc0MkbIKybzLlb4VBjVGNiy8trnfx1W/nr1Dbl68=
然后,我寫了一個Ruby程序來計算字符串"Hello"
Base64編碼的SHA-256哈希,通過在Ruby的所有支持的char編碼中編碼字符串來確定哪個char編碼將給出完全相同的結果。
require "digest/sha2"
require "base64"
s = "Hello"
Encoding.list.each { |e| puts "Encoding: #{e.to_s} => Hash: #{Digest::SHA256.base64digest(s.encode(e)) rescue "error"}"}
運行程序后,我得出結論,如果你使用UTF-16LE
編碼,你將獲得完全相同的輸出。
p hash = Digest::SHA256.base64digest("Hello".encode('UTF-16LE'))
根據UnicodeEncoding
文檔 ,它:
表示Unicode字符的UTF-16編碼。
我認為您應該將new UnicodeEncoding()
更改為new UTF8Encoding()
或僅使用Encoding.UTF8
Unicode在C#中是UTF-16
K所以這是一個很多項目。 在C# UnicodeEncoding().GetBytes(str)
顯然在每個字符后面添加一個0到字節數組。 所以我不得不在Ruby中解決這個問題。 幸運的是,我能夠使用一點紅寶石魔法來做到這一點。 完整的工作解決方案如下。
byte_array = input.bytes.zip(input.bytes.map{|b| 0}).flatten.compact
Digest::SHA256.base64digest(byte_array.pack('C*').force_encoding('utf-16'))
這給了我一個與數據庫中的值匹配的相同哈希輸出。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.