SHA1:将 JavaScript 实现转换为 C#

发布于 2024-10-10 16:13:50 字数 2029 浏览 4 评论 0原文

我正在尝试使用 https://www.interactivebrokers.com/sso/Login 登录ac# 客户端。有一个步骤涉及根据用户名和密码创建 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))

使用相同的用户名& javascript 和 .net 中的密码,它似乎会生成不同的结果。

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

那么,是否已经有一些 SHA1 实现可以与可用的 JavaScript 实现执行相同的操作?或者,如果我确实需要自己实现这一点,如何移植 str2blks_SHA1()?

谢谢

I'm trying to login to https://www.interactivebrokers.com/sso/Login using a c# client. There's a step that involves creating a sha1 hash from the username & password ( https://www.interactivebrokers.com/sso/Templates/javascript/myxyz.js , line 203):

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

this calls ( https://www.interactivebrokers.com/sso/Templates/javascript/sha1.js , line 113)

calcSHA1Blks(str2blks_SHA1(str);

and str2blks_SHA1() is defined ( https://www.interactivebrokers.com/sso/Templates/javascript/sha1.js , line 28) as

/*
 * 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;
}

I'm not all that familiar with SHA1 stuff, so I can't tell if what's in str2blks_SHA1() is standard stuff that is done automatically inside .net's SHA1CryptoServiceProvider.ComputeHash(), or if it's something I need to do explicitly. I tried:

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

using the same username & password in javascript and in .net, and it seems to generate a different result.

Then I tried to port that str2blks_SHA1() function to c#, but I don't understand how to create an array of bytes (blks) (which SHA1CryptoServiceProvider.ComputeHash() requires), as it seems like each array item in blks could be larger than a byte (just looking at str.length * 8))...

So, is there already some SHA1 implementation that does the same thing as this javascript implementation available? Or if I really do need to implement this myself, how do I port str2blks_SHA1()?

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

深海里的那抹蓝 2024-10-17 16:13:50

此 JavaScript 实现看起来类似于 RFC 3174 中的标准 SHA-1 填充算法。我从运行中得到相同的结果(忽略细微的格式差异):

// JavaScript
calcSHA1("[email protected]:p4ssw0rd");

就像我从以下内容中得到的结果一样:

// C#
using (SHA1 hash = SHA1.Create())
    Console.WriteLine(BitConverter.ToString(
        hash.ComputeHash(Encoding.ASCII.GetBytes("[email protected]:p4ssw0rd"))));

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

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

This JavaScript implementation looks like the standard SHA-1 padding algorithm from RFC 3174. I get the same results (ignoring minor formatting differences) from running:

// JavaScript
calcSHA1("[email protected]:p4ssw0rd");

as I do from:

// C#
using (SHA1 hash = SHA1.Create())
    Console.WriteLine(BitConverter.ToString(
        hash.ComputeHash(Encoding.ASCII.GetBytes("[email protected]:p4ssw0rd"))));

What data are you supplying and what (different) results are you getting?

(Note that if your username or password contain non-ASCII characters, I wouldn't be surprised for the JavaScript to generate a different result than C#, because it doesn't appear to be doing a proper UTF-8 conversion; specifically, it appears to assume that each character is just one byte.)

狼性发作 2024-10-17 16:13:50

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

Have you tried setting SHA1's InputBlockSize or OutputBlockSize ?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文