Secure random token in Node.js

后端 未结 12 914
盖世英雄少女心
盖世英雄少女心 2020-11-28 00:05

In this question Erik needs to generate a secure random token in Node.js. There\'s the method crypto.randomBytes that generates a random Buffer. However, the ba

相关标签:
12条回答
  • 2020-11-28 00:47

    0. Using nanoid third party library [NEW!]

    A tiny, secure, URL-friendly, unique string ID generator for JavaScript

    https://github.com/ai/nanoid

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


    1. Base 64 Encoding with URL and Filename Safe Alphabet

    Page 7 of RCF 4648 describes how to encode in base 64 with URL safety. You can use an existing library like base64url to do the job.

    The function will be:

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

    Usage example:

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

    Note that the returned string length will not match with the size argument (size != final length).


    2. Crypto random values from limited set of characters

    Beware that with this solution the generated random string is not uniformly distributed.

    You can also build a strong random string from a limited set of characters like that:

    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');
    }
    

    Usage example:

    randomAsciiString(20);
    // Returns 'rmRptK5niTSey7NlDk5y' which is 20 characters length.
    
    randomString(20, 'ABCDEFG');
    // Returns 'CCBAAGDGBBEGBDBECDCE' which is 20 characters length.
    
    0 讨论(0)
  • 2020-11-28 00:51

    https://www.npmjs.com/package/crypto-extra has a method for it :)

    var value = crypto.random(/* desired length */)
    
    0 讨论(0)
  • 2020-11-28 00:51

    crypto-random-string is a nice module for this.

    const cryptoRandomString = require('crypto-random-string');
     
    cryptoRandomString({length: 10});
    // => '2cf05d94db'
     
    cryptoRandomString({length: 10, type: 'base64'});
    // => 'YMiMbaQl6I'
     
    cryptoRandomString({length: 10, type: 'url-safe'});
    // => 'YN-tqc8pOw'
     
    cryptoRandomString({length: 10, type: 'numeric'});
    // => '8314659141'
     
    cryptoRandomString({length: 6, type: 'distinguishable'});
    // => 'CDEHKM'
     
    cryptoRandomString({length: 10, type: 'ascii-printable'});
    // => '`#Rt8$IK>B'
     
    cryptoRandomString({length: 10, type: 'alphanumeric'});
    // => 'DMuKL8YtE7'
     
    cryptoRandomString({length: 10, characters: 'abc'});
    // => 'abaaccabac'
    

    cryptoRandomString.async(options) add .async if you want to get a promise.

    0 讨论(0)
  • 2020-11-28 00:52

    Check out:

    var crypto = require('crypto');
    crypto.randomBytes(Math.ceil(length/2)).toString('hex').slice(0,length);
    
    0 讨论(0)
  • 2020-11-28 00:52

    Look at real_ates ES2016 way, it's more correct.

    ECMAScript 2016 (ES7) way

    import crypto from 'crypto';
    
    function spawnTokenBuf() {
        return function(callback) {
            crypto.randomBytes(48, callback);
        };
    }
    
    async function() {
        console.log((await spawnTokenBuf()).toString('base64'));
    };
    

    Generator/Yield Way

    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'));
    });
    
    0 讨论(0)
  • 2020-11-28 00:52

    Simple function that gets you a token that is URL safe and has base64 encoding! It's a combination of 2 answers from above.

    const randomToken = () => {
        crypto.randomBytes(64).toString('base64').replace(/\//g,'_').replace(/\+/g,'-');
    }
    
    0 讨论(0)
提交回复
热议问题