如何在节点 js 中使用随机数、时间戳和密码创建摘要密码

Posted

技术标签:

【中文标题】如何在节点 js 中使用随机数、时间戳和密码创建摘要密码【英文标题】:How to create digest password using nonce, timestamp and password in node js 【发布时间】:2020-08-18 16:03:55 【问题描述】:

我正在使用 express 创建一个应用程序。我有一个 SOAP API 请求。在这个 SOAP API 中,我必须发送随机数、时间戳和摘要密码。首先,我用 php 尝试了这个,我成功发送了请求并得到了响应。现在我也想用 Node Js 来做这件事。然后我尝试了 wsse npm 包。但是,这并没有创建正确的密码。这是我尝试过的。

const wsse = require('wsse');

const token2 = new wsse.UsernameToken(
      username: 'hdfhrhe',                           // (required)
      password: 'ergerherh',                // (required)
      created: Timestamp,           // (optional) you can specify `craeted`.
      nonce: NonceWithEncode, // (optional) you can specify `nonce`.
      sha1encoding: 'hex'                        // (optional) you can specify `sha1encoding` for wrong WSSE Username Token implementation.
    );
console.log(token2.getWSSEHeader());

我需要做什么。

digest_pw = Base64 ( SHA-1 ( nonce + timestamp+ SHA-1 ( password ) ) );

我该怎么做?有什么方法吗??

【问题讨论】:

目前还不清楚究竟是什么不起作用。你有什么错误吗? 由于 PHP 代码似乎为 digest_pw 提供了正确的结果,因此相应的代码可能会有所帮助。 【参考方案1】:

首先你必须需要加密库:

const crypto = require('crypto');

然后,定义一些函数:

function someId() 
  // function taken from https://***.com/questions/105034/how-to-create-a-guid-uuid
  // creates a random 20 characters hex string
  return 'xxxxxxxxxxxxxxxxxxxx'.replace(/x/g, function(c) 
    var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
    return v.toString(16);
  );


function md5(str, encoding) 
  return crypto.createHash('md5').update(str).digest(encoding);


function passwordDigest(created, nonce, pass) 
  // Password_Digest = Base64 ( SHA-1 ( bytes(decode64(nonce)) + bytes(created) + bytes(password) ) )
  let pd = Int8Array.from([...Int8Array.from(Buffer.from(nonce, 'base64')),
                           ...Int8Array.from(Buffer.from(created)),
                           ...Int8Array.from(Buffer.from(pass))]);
  pd = crypto.createHash('sha1').update(pd).digest('base64');
  return pd;


// for example
// console.log(passwordDigest('2006-07-26T15:16:00.925Z', 'lckJBnhGHAj4EGG3YuGXmg==', '1111'));
// must print 'LiP3J84wKHpA6sMOu2BVVZRGYSY='

现在您可以计算变量以将它们嵌入到标题中:

const usernametoken = `UsernameToken-$Math.round(Math.random()*10000000).toString()`;
const username = 'myUserName';
const passwd = 'myPassword'; // this will not be sent
const created = (new Date).toISOString();
const nonce = md5(someId().substr(0,16), 'base64'); // Only 16 characters length before md5!
const passworddigest = passwordDigest(created, nonce, passwd);

然后你替换你在soap头中计算的变量:

const header = `<soapenv:Header>
      <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
        <wsse:UsernameToken wsu:Id="$usernametoken" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
          <wsse:Username>$username</wsse:Username>
          <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest">$passworddigest</wsse:Password>
          <wsse:Nonce>$nonce</wsse:Nonce>
          <wsu:Created>$created</wsu:Created>
        </wsse:UsernameToken>
      </wsse:Security>
    </soapenv:Header>`;

因此,最后,您必须在 之前将此标头嵌入到 中。

【讨论】:

以上是关于如何在节点 js 中使用随机数、时间戳和密码创建摘要密码的主要内容,如果未能解决你的问题,请参考以下文章

如何将 html 数据从节点 js 发送到前端?

使用节点 js、AngularJs 和 JWT 使用用户名和密码进行身份验证

如何在 python 中制作 HTML5 Geolocation 对象?

如何创建密码重置链接?

如何在 Rust Diesel 中使用时间戳和间隔进行算术运算

节点JS错误:无效密码