首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在NodeJS Javascript中匹配HttpServerUtility.UrlTokenEncode的输出

在NodeJS Javascript中匹配HttpServerUtility.UrlTokenEncode的输出
EN

Stack Overflow用户
提问于 2020-03-20 04:29:25
回答 2查看 226关注 0票数 1

我正在查看dotnet中的一个示例,它看起来如下所示:https://dotnetfiddle.net/t0y8yD

HttpServerUtility.UrlTokenEncode方法的输出为:

代码语言:javascript
复制
Pn55YBwEH2S2BEM5qlNrq-LMNE8BDdHYwbWKFEHiPZo1

当我尝试使用encodeURIencodeURIComponent或任何其他尝试在NodeJS中完成相同的操作时,会得到以下结果:

代码语言:javascript
复制
Pn55YBwEH2S2BEM5qlNrq+LMNE8BDdHYwbWKFEHiPZo=

从上面可以看出,'-‘应该是'+’,最后一个字符部分是不同的。散列是以相同的方式创建的,并输出相同的缓冲区。

代码语言:javascript
复制
  var hmac = crypto.createHmac("sha256", buf);
  hmac.update("9644873");
  var hash = hmac.digest("base64");

我怎样才能使两者匹配呢?另一个重要的注意是,这只是一个用例,我不确定是否有其他字符做同样的事情。

我不确定是dotnet变体不正确还是NodeJS版本不正确。但是,比较是在dotnet端进行的,所以我需要node来匹配它。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-03-20 06:56:21

两个结果的差异是由于在C#代码中使用了Base64URL编码,而在node.js中使用了Base64编码。

Base64URLBase64几乎相同,但Base64编码使用字符+/=,这些字符在URL中有特殊含义,因此必须避免使用。在Base64URL编码中,+被替换为-/被替换为_= (末尾的填充字符)被替换为%20,或者干脆被省略。

在您的代码中,您正在计算一个HMAC-SHA256散列,因此您将得到一个256位的结果,它可以被编码为32个字节。在Base64/Base64URL中,每个字符代表6位,因此需要256/6 = 42,66 => 43 Base64字符。对于43个字符,您将在末尾有2个“lonesome”位,因此添加了填充字符(=)。现在的问题是,为什么HttpServerUtility.UrlTokenEncode在末尾添加了一个1来代替填充字符。我在documentation里什么也没找到。但是你,你应该记住,无论如何它都是微不足道的。

要在node.js中获得相同的结果,您可以使用包base64url,或者只对base64编码的散列使用简单的replace语句。

使用base64url包:

代码语言:javascript
复制
const base64url = require('base64url');
var hmacB64 = "Pn55YBwEH2S2BEM5qlNrq+LMNE8BDdHYwbWKFEHiPZo="
var hmacB64url = base64url.fromBase64(hmacb64)

console.log(hmacB64url)

结果是:

代码语言:javascript
复制
Pn55YBwEH2S2BEM5qlNrq-LMNE8BDdHYwbWKFEHiPZo

如你所见,这个库只是省略了填充字符。

使用replace,还将填充=替换为1

代码语言:javascript
复制
var hmacB64 = "Pn55YBwEH2S2BEM5qlNrq+LMNE8BDdHYwbWKFEHiPZo="
console.log(hmacb64.replace(/\//g,'_').replace(/\+/g,'-').replace(/\=+$/m,'1'))

结果是:

代码语言:javascript
复制
Pn55YBwEH2S2BEM5qlNrq-LMNE8BDdHYwbWKFEHiPZo1

我用不同的数据尝试了C#代码,最后总是得到'1‘,所以用1替换=似乎是可以的,尽管它似乎不符合RFC。

另一种选择是更改C#代码。使用普通的base64编码加上字符串替换来获得base64url输出,而不是使用HttpServerUtility.UrlTokenEncode

here描述了一种可能的解决方案

票数 1
EN

Stack Overflow用户

发布于 2020-03-27 07:55:28

我是新来的,所以我不能评论(需要50个声誉),但我想在@jqs答案中加上,如果字符串以两个"=“结尾,则替换需要以"2”结束。所以我的替换看起来像这样:

Hmacb64.替换(/g,'_').replace(/+/g,'-').replace(/\=\=$/m,'2').replace(/\=$/m,'1')

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60764586

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档