SHA1:将javascript实现转换为c#

时间:2011-01-04 03:18:24

标签: javascript .net hash sha1

我正在尝试使用c#客户端登录https://www.interactivebrokers.com/sso/Login。有一个步骤涉及从用户名&创建一个sha1哈希。密码(https://www.interactivebrokers.com/sso/Templates/javascript/myxyz.js,第203行):

innerHash = CalcSHA1(username + ":" + password);  

此调用(https://www.interactivebrokers.com/sso/Templates/javascript/sha1.js,第113行)

calcSHA1Blks(str2blks_SHA1(str);

和str2blks_SHA1()被定义为(https://www.interactivebrokers.com/sso/Templates/javascript/sha1.js,第28行)为

/*
 * Convert a string to a sequence of 16-word blocks, stored as an array.
 * Append padding bits and the length, as described in the SHA1 standard.
 */
function str2blks_SHA1(str)
{
  var nblk = ((str.length + 8) >> 6) + 1;
  var blks = new Array(nblk * 16);
  for(var i = 0; i < nblk * 16; i++) blks[i] = 0;
  for(i = 0; i < str.length; i++)
    blks[i >> 2] |= str.charCodeAt(i) << (24 - (i % 4) * 8);
  blks[i >> 2] |= 0x80 << (24 - (i % 4) * 8);
  blks[nblk * 16 - 1] = str.length * 8;
  return blks;
}

我不是很熟悉SHA1的东西,所以我不知道str2blks_SHA1()中的内容是否是在.net的SHA1CryptoServiceProvider.ComputeHash()中自动完成的标准内容,或者是否是我需要做的事情明确。我试过了:

SHA1CryptoServiceProvider.ComputeHash(Encoding.UTF8.GetBytes(userName + ":" + password))

使用相同的用户名和&amp;在javascript和.net中的密码,它似乎产生了不同的结果。

然后我尝试将str2blks_SHA1()函数移植到c#,但我不明白如何创建一个字节数组(blks)(SHA1CryptoServiceProvider.ComputeHash()需要),因为它似乎是每个数组项blks可能大于一个字节(只看str.length * 8))...

那么,是否已经有一些SHA1实现与这个javascript实现相同?或者如果我确实需要自己实现,我该如何移植str2blks_SHA1()?

由于

2 个答案:

答案 0 :(得分:1)

此JavaScript实现类似于RFC 3174中的标准SHA-1填充算法。我从运行中获得了相同的结果(忽略了较小的格式差异):

// JavaScript
calcSHA1("username@example.com:p4ssw0rd");

正如我所做的那样:

// C#
using (SHA1 hash = SHA1.Create())
    Console.WriteLine(BitConverter.ToString(
        hash.ComputeHash(Encoding.ASCII.GetBytes("username@example.com:p4ssw0rd"))));

您提供了哪些数据?您获得了哪些(不同的)结果?

(请注意,如果您的用户名或密码包含非ASCII字符,我不会对JavaScript生成与C#不同的结果感到惊讶,因为它似乎没有进行正确的UTF-8转换;具体来说,似乎假设每个字符只是一个字节。)

答案 1 :(得分:0)

您是否尝试过设置SHA1的InputBlockSize或OutputBlockSize?