繁体   English   中英

C# SHA256 ComputeHash 结果与 CryptoJS SHA256 不同 function

[英]C# SHA256 ComputeHash result different with CryptoJS SHA256 function

我有一个 C# function 如下:

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 function 匹配上面的代码,这样 C# 和 JS 的最终结果是相同的。

目前在我的 JS 代码中,我正在使用这个:

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

这是我的 hexhash 的结果:

d956678c8f12c65299daf35019a9a1eb3e6eb9855fd850aeb5aafe46057d179e

但是在我的 C# 代码中,这行var digest = ssp.ComputeHash(bPass); 返回以下数组: 在此处输入图像描述

我对编码了解不多。 请告诉我上面的 c# 代码中填充的是什么类型的结果? 如果我没记错的话,ComputeHash 正在返回字节,但我需要大量阅读才能确认这又是一个漫长的学习时间

我尝试了许多不同的方法来转换 JS Sha256 代码,但没有成功。 我在这条特定的线路上停留了将近一天。

请帮忙。 谢谢

编辑:抱歉代码错误。 我已经更新了 C# 代码。 ComputeHash 接受一个数组

在我的示例中,我使用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个字符。

经过无数次的反复试验后,我终于找到了答案。

C#代码var digest = ssp.ComputeHash(encodedvalue)var encodedvalue= Encoding.Unicode.GetBytes(stringvalue);的结果返回字节数组var encodedvalue= Encoding.Unicode.GetBytes(stringvalue); 正如让回答。 为了在Javascript中创建函数,我需要确保encodedvalue生成正确的编码格式和大小,就像在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;
    }

希望它能帮助那些需要这种方法的人

尝试

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

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

该js库在计算其哈希值之前将字符串转换为UTF8。

替代Koo SengSeng的答案(如果你不想使用CryptoJS库)。
SHA256函数就是从这里开始的arrToUintArr函数来自Koo SengSeng的答案。

var SHA256=function a(b){function c(a,b){return a>>>b|a<<32-b}for(var d,e,f=Math.pow,g=f(2,32),h="length",i="",j=[],k=8*b[h],l=a.h=a.h||[],m=a.k=a.k||[],n=m[h],o={},p=2;64>n;p++)if(!o[p]){for(d=0;313>d;d+=p)o[d]=p;l[n]=f(p,.5)*g|0,m[n++]=f(p,1/3)*g|0}for(b+="\x80";b[h]%64-56;)b+="\x00";for(d=0;d<b[h];d++){if(e=b.charCodeAt(d),e>>8)return;j[d>>2]|=e<<(3-d)%4*8}for(j[j[h]]=k/g|0,j[j[h]]=k,e=0;e<j[h];){var q=j.slice(e,e+=16),r=l;for(l=l.slice(0,8),d=0;64>d;d++){var s=q[d-15],t=q[d-2],u=l[0],v=l[4],w=l[7]+(c(v,6)^c(v,11)^c(v,25))+(v&l[5]^~v&l[6])+m[d]+(q[d]=16>d?q[d]:q[d-16]+(c(s,7)^c(s,18)^s>>>3)+q[d-7]+(c(t,17)^c(t,19)^t>>>10)|0),x=(c(u,2)^c(u,13)^c(u,22))+(u&l[1]^u&l[2]^l[1]&l[2]);l=[w+x|0].concat(l),l[4]=l[4]+w|0}for(d=0;8>d;d++)l[d]=l[d]+r[d]|0}for(d=0;8>d;d++)for(e=3;e+1;e--){var y=l[d]>>8*e&255;i+=(16>y?0:"")+y.toString(16)}return i};
var arrToUintArr=function(a){for(var l=a.length,b=new Uint8Array(l<<2),o=0,w,i=0;i<l;i++) w=a[i],b[o++]=w>>24,b[o++]=(w>>16)&0xff,b[o++]=(w>>8)&0xff,b[o++]=w&0xff;return b;}
var computeHash=function(k){for(var a=[],s=SHA256(k),i=0;i<8;i++) a.push(parseInt(s.substr(i*8,8),16));return arrToUintArr(a);}

computeHash(k)将返回表示字节的数字数组。

这等于C#中的以下代码:

new System.Security.Cryptography.SHA256CryptoServiceProvider().ComputeHash(Encoding.UTF8.GetBytes(k));

打字稿代码:

private computeHash(text: string): string {
    return CryptoJS.SHA256(text).toString();
}

C# 等效:

private string ComputeHash(string text)
{
    using (var sha256 = SHA256.Create())
    {
       var bytes = Encoding.UTF8.GetBytes(text);
       var hash = sha256.ComputeHash(bytes);
       return hash.Aggregate(string.Empty, (current, x) => current + $"{x:x2}");
    }
}

经过两天的研究,它完美地工作。 两个不同的代码给出相同的结果。

js

const sha1 = require('sha1');    
const getHash = str =>{
    const hashingBytes = Buffer.from(sha1(str), "hex");
    const base64Value = Buffer.from(hashingBytes).toString('base64');
    return base64Value;
}

c#

 System.Security.Cryptography.SHA1 sha = new System.Security.Cryptography.SHA1CryptoServiceProvider();
        byte[] bytes = System.Text.Encoding.ASCII.GetBytes(str);
        byte[] hashingbytes = sha.ComputeHash(bytes);
        var hash = Convert.ToBase64String(hashingbytes);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM