2016-03-14 160 views
3

我有如下一個C#函數:C#SHA256 ComputeHash導致與CryptoJS SHA256功能不同

string stringvalue = "530500480530490480530480480520570480520510500490"; 
var encodedvalue= Encoding.Unicode.GetBytes(stringvalue); 
using (HashAlgorithm ssp = System.Security.Cryptography.HashAlgorithm.Create("SHA256")) 
     { 

      var digest = ssp.ComputeHash(encodedvalue); 

      return BitConverter.ToString(digest); 

     } 

我需要創建的代碼匹配上述那一個JavaScript功能,使得兩者的最終結果C#和JS是一樣。

在我的JS代碼

目前,我使用的是這樣的:

var hash = CryptoJS.SHA256("530500480530490480530480480520570480520510500490"); 
var hexhash = hash.toString(CryptoJS.enc.hex); 

這是我hexhash的結果:

d956678c8f12c65299daf35019a9a1eb3e6eb9855fd850aeb5aafe46057d179e 

但在我的C#代碼,這行var digest = ssp.ComputeHash(bPass);回報以下數組: enter image description here

我對編碼知之甚少。請告訴我在上面的c#代碼中填充了什麼類型的結果?如果我沒有弄錯,ComputeHash會返回字節,但我需要大量的讀數來確認哪個是另一個長時間的學習

我嘗試了許多不同的方式來轉換JS Sha256代碼,但沒有運氣。我在這個特定的線路上停留了將近一天。

請幫忙。謝謝

編輯: 對不起,發生代碼錯誤。我更新了C#代碼。 ComputeHash接受陣列

+0

那'ComputeHash'不直接接受'string'參數得到的匹配結果。該代碼甚至不會編譯。 – xanatos

回答

0

嘗試

var digest = ssp.ComputeHash(Encoding.UTF8.GetBytes(stringvalue)) 

return BitConverter.ToString(digest) 
        .Replace("-", string.Empty) 
        .ToLowerInvariant(); 

那JS庫計算其哈希前的字符串轉換爲UTF-8。

2

在我的例子中,我使用System.Security.Cryptography.SHA256Managed在C#中獲得SHA256。

方法SHA256Managed.ComputeHash將一個字節數組作爲參數並返回另一個字節數組。現在我們需要將您的字節數組轉換爲一個字符串。

以下代碼返回一個Javascript SHA-256的相同結果。

byte[] bytes = Encoding.UTF8.GetBytes("530500480530490480530480480520570480520510500490"); 
SHA256Managed hashstring = new SHA256Managed(); 
byte[] hash = hashstring.ComputeHash(bytes); 
string hashString = string.Empty; 
foreach (byte x in hash) 
{ 
    hashString += String.Format("{0:x2}", x); 
} 
return(hashString); 

只是爲了解釋:的String.Format( 「{0:X2}」,x)的

  • X表示十六進制格式。
  • 2表示2個字符。
+0

感謝您的回答。但是,而不是改變C#功能,無論如何,我可以改變JavaScript中的代碼來實現在C#中的結果?目前我需要創建一個新的JavaScript代碼來匹配C#函數,我不能在我的程序中使用C#函數 –

+0

這不是實現它的更好方法,但是如果您不想將其添加到JS中發現任何其他問題:'var hexhash = hash.toString(CryptoJS.enc.hex).toUpperCase(); hexhash = hexhash.replace(/(\ S {2})/ g,「$ 1-」); \t hexhash = hexhash.replace(/ - $ /,「」);' 此輸出與您在C#中的返回結果相同。 –

3

我經過無數次的試錯,終於找到了答案。

Jean答覆時,C#代碼var digest = ssp.ComputeHash(encodedvalue)正在從var encodedvalue= Encoding.Unicode.GetBytes(stringvalue);的結果返回字節數組。爲了在Javascript中創建函數,我需要確保編碼值正如C#中那樣生成正確的編碼格式和大小。

只使用CryptoJS,我設法從下面

function GetHexFromString() { 
var stringVal = '8563A578-7402-4567-A6CE-4DE4E0825B021234'; 
// Convert the string to UTF 16 little-endian 
// Result: 560530540510650530550560450550520480500450520530540550450650540670690450520680690520690480560500530660480500490500510520 
var utf16le = CryptoJS.enc.Utf16LE.parse(stringVal); 

// Convert to Sha256 format and get the word array 
var utf16Sha256 = CryptoJS.SHA256(utf16le); 
// Convert the Sha256 word array to Uint8Array to get the 32 byte array just to see the result to ensure it match with the C# function 
// Result: 94,203,69,29,35,202,209,149,121,144,44,6,98,250,141,161,102,7,238,35,228,117,111,236,118,115,51,113,134,72,52,69 
var utf16sha256Array = convertWordArrayToUint8Array(utf16Sha256); 

// Convert the Sha256 to hex (if i'm not mistaken, it's base 16) format 
var hexSha256 = utf16Sha256.toString(CryptoJS.enc.hex); 

// Insert a dash in between 2 characters in the string 
hexSha256 = hexSha256.replace(/(\S{2})/g, "$1-"); 
// Remove the last dash in the string 
hexSha256 = hexSha256.replace(/-$/, ""); 

// Final Result: 5E-CB-45-1D-23-CA-D1-95-79-90-2C-06-62-FA-8D-A1-66-07-EE-23-E4-75-6F-EC-76-73-33-71-86-48-34-45 
return hexSha256.toUpperCase(); 
} 

function convertWordArrayToUint8Array(wordArray) { 
     var len = wordArray.words.length, 
      u8_array = new Uint8Array(len << 2), 
      offset = 0, word, i 
     ; 
     for (i = 0; i < len; i++) { 
      var word = wordArray.words[i];     

      u8_array[offset++] = word >> 24; 
      u8_array[offset++] = (word >> 16) & 0xff; 
      u8_array[offset++] = (word >> 8) & 0xff; 
      u8_array[offset++] = word & 0xff;            
     } 
     return u8_array; 
    } 

希望它能幫助無論是誰需要這樣的方法