【问题标题】:SHA1: translating javascript implementation to c#SHA1:将 javascript 实现转换为 c#
【发布时间】:2011-06-03 04:27:29
【问题描述】:

我正在尝试使用 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))

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

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

那么,是否已经有一些 SHA1 实现与这个可用的 javascript 实现做同样的事情?或者如果我真的需要自己实现这个,我该如何移植 str2blks_SHA1()?

谢谢

【问题讨论】:

  • 如果可能的话,您永远不应该实现自己的加密例程。对它们有太多可能的侧信道攻击,您几乎肯定会失去加密安全性。

标签: javascript .net hash sha1


【解决方案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 转换;具体来说,它似乎假设每个字符只有一个字节。)

【讨论】:

  • 你是对的,它确实有效。我试图将结果与 BigInteger 进行比较; ComputeHash() 的字节数组结果在传递给 BigInteger 的构造函数之前必须反转,然后两个结果匹配。嗯......我是对的,它是必须反转的字节数组,而不是来自 javascript 版本的字符串? (即,确保一切仍然适用于 BigInteger.ModPow() 和所有这些东西)
  • 如果您想将 SHA-1 输出视为 160 位数字,您通常希望以大端顺序对其进行解释。由于构造的 BigInteger 被记录为以 little-endian 顺序获取字节数组,因此您是正确的,需要反转 C# 字节数组才能使 BigInteger 具有所需的值。
【解决方案2】:

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

【讨论】:

    猜你喜欢
    • 2014-09-25
    • 1970-01-01
    • 1970-01-01
    • 2019-09-18
    • 2013-07-08
    • 2016-06-02
    • 1970-01-01
    • 2014-12-04
    • 2021-07-31
    相关资源
    最近更新 更多