在Node.js中保护随机令牌

2020/10/07 19:01 · javascript ·  · 0评论

这个问题中, Erik需要在Node.js中生成一个安全的随机令牌。有一种crypto.randomBytes生成随机缓冲区的方法但是,node中的base64编码不是网址安全的,它包含/+而不是-_因此,我发现生成这种令牌的最简单方法是

require('crypto').randomBytes(48, function(ex, buf) {
    token = buf.toString('base64').replace(/\//g,'_').replace(/\+/g,'-');
});

有没有更优雅的方式?

尝试crypto.randomBytes()

require('crypto').randomBytes(48, function(err, buffer) {
  var token = buffer.toString('hex');
});

“十六进制”编码在节点v0.6.x或更高版本中有效。

如果您不是像我这样的JS专家,请使用同步选项。不得不花一些时间在如何访问内联函数变量上

var token = crypto.randomBytes(64).toString('hex');

0.使用nanoid第三方库[NEW!]

一个很小的,安全的,URL友好的,唯一的JavaScript字符串ID生成器

https://github.com/ai/nanoid

import { nanoid } from "nanoid";
const id = nanoid(48);

1.使用URL和文件名安全字母进行Base 64编码

RCF 4648的第7页介绍了如何使用URL安全性在base 64中进行编码。您可以使用现有的库(例如base64url)来完成这项工作。

该函数将是:

var crypto = require('crypto');
var base64url = require('base64url');

/** Sync */
function randomStringAsBase64Url(size) {
  return base64url(crypto.randomBytes(size));
}

用法示例:

randomStringAsBase64Url(20);
// Returns 'AXSGpLVjne_f7w5Xg-fWdoBwbfs' which is 27 characters length.

请注意,返回的字符串长度将与size参数不匹配(size!=最终长度)。

2.来自有限字符集的加密随机值

请注意,使用此解决方案时,生成的随机字符串不是均匀分布的。

您还可以从有限的一组字符中构建一个强大的随机字符串,如下所示:

var crypto = require('crypto');

/** Sync */
function randomString(length, chars) {
  if (!chars) {
    throw new Error('Argument \'chars\' is undefined');
  }

  var charsLength = chars.length;
  if (charsLength > 256) {
    throw new Error('Argument \'chars\' should not have more than 256 characters'
      + ', otherwise unpredictability will be broken');
  }

  var randomBytes = crypto.randomBytes(length);
  var result = new Array(length);

  var cursor = 0;
  for (var i = 0; i < length; i++) {
    cursor += randomBytes[i];
    result[i] = chars[cursor % charsLength];
  }

  return result.join('');
}

/** Sync */
function randomAsciiString(length) {
  return randomString(length,
    'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789');
}

用法示例:

randomAsciiString(20);
// Returns 'rmRptK5niTSey7NlDk5y' which is 20 characters length.

randomString(20, 'ABCDEFG');
// Returns 'CCBAAGDGBBEGBDBECDCE' which is 20 characters length.

使用异步和等待的ES 2016标准(从节点7开始)异步执行此操作的最新正确方法如下:

const crypto = require('crypto');

function generateToken({ stringBase = 'base64', byteLength = 48 } = {}) {
  return new Promise((resolve, reject) => {
    crypto.randomBytes(byteLength, (err, buffer) => {
      if (err) {
        reject(err);
      } else {
        resolve(buffer.toString(stringBase));
      }
    });
  });
}

async function handler(req, res) {
   // default token length
   const newToken = await generateToken();
   console.log('newToken', newToken);

   // pass in parameters - adjust byte length
   const shortToken = await generateToken({byteLength: 20});
   console.log('newToken', shortToken);
}

无需任何Babel转换即可在Node 7中直接使用

随机URL和文件名字符串安全(1个衬里)

Crypto.randomBytes(48).toString('base64').replace(/\+/g, '-').replace(/\//g, '_').replace(/\=/g, '');

退房:

var crypto = require('crypto');
crypto.randomBytes(Math.ceil(length/2)).toString('hex').slice(0,length);

随着异步/等待和承诺

const crypto = require('crypto')
const randomBytes = Util.promisify(crypto.randomBytes)
const plain = (await randomBytes(24)).toString('base64').replace(/\W/g, '')

产生类似于 VjocVHdFiz5vGHnlnwqJKN0NdeHcz8eM

看一下real_atesES2016的方式,它更正确。

ECMAScript 2016(ES7)方式

import crypto from 'crypto';

function spawnTokenBuf() {
    return function(callback) {
        crypto.randomBytes(48, callback);
    };
}

async function() {
    console.log((await spawnTokenBuf()).toString('base64'));
};

发电机/发电方式

var crypto = require('crypto');
var co = require('co');

function spawnTokenBuf() {
    return function(callback) {
        crypto.randomBytes(48, callback);
    };
}

co(function* () {
    console.log((yield spawnTokenBuf()).toString('base64'));
});

https://www.npmjs.com/package/crypto-extra有一种方法:)

var value = crypto.random(/* desired length */)

npm模块anyid提供了灵活的API,可以生成各种字符串ID /代码。

要使用48个随机字节在A-Za-z0-9中生成随机字符串:

const id = anyid().encode('Aa0').bits(48 * 8).random().id();
// G4NtiI9OYbSgVl3EAkkoxHKyxBAWzcTI7aH13yIUNggIaNqPQoSS7SpcalIqX0qGZ

要生成固定长度的仅由随机字节填充的字母字符串:

const id = anyid().encode('Aa').length(20).random().id();
// qgQBBtDwGMuFHXeoVLpt

在内部,它用于crypto.randomBytes()生成随机数。

一个简单的函数,可为您提供URL安全且具有base64编码的令牌!它是上面两个答案的组合。

const randomToken = () => {
    crypto.randomBytes(64).toString('base64').replace(/\//g,'_').replace(/\+/g,'-');
}
本文地址:http://javascript.askforanswer.com/zainode-jszhongbaohusuijilingpai.html
文章标签: ,   ,   ,  
版权声明:本文为原创文章,版权归 javascript 所有,欢迎分享本文,转载请保留出处!

文件下载

老薛主机终身7折优惠码boke112

上一篇:
下一篇:

评论已关闭!