381 Stimmen

Sicheres zufälliges Token in Node.js

En diese Frage Erik muss ein sicheres zufälliges Token in Node.js erzeugen. Es gibt die Methode crypto.randomBytes die einen zufälligen Puffer erzeugt. Die base64-Kodierung in node ist jedoch nicht url-sicher, sie enthält / y + 代わりに - y _ . Daher ist der einfachste Weg, ein solches Token zu erzeugen, der folgende

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

Gibt es einen eleganteren Weg?

475voto

thejh Punkte 43512

Versuchen Sie crypto.randomBytes() :

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

Die 'hex'-Kodierung funktioniert in node v0.6.x oder neuer.

352voto

phoenix2010 Punkte 3383

Synchrone Option für den Fall, dass Sie nicht ein JS-Experte wie ich sind. Musste einige Zeit damit verbringen, wie man auf die Inline-Funktionsvariable zugreift

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

114voto

Yves M. Punkte 28190

1. Verwendung der nanoid-Bibliothek von Drittanbietern [NEU!]


Ein kleiner, sicherer, URL-freundlicher, eindeutiger String-ID-Generator für JavaScript

https://github.com/ai/nanoid

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

2. Base 64 Kodierung mit URL und Dateinamen Safe Alphabet


Seite 7 von RCF 4648 beschreibt, wie man in Base 64 mit URL-Sicherheit kodiert. Sie können eine bestehende Bibliothek verwenden wie base64url um die Arbeit zu erledigen.

Die Funktion wird sein:

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

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

Beispiel für die Verwendung:

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

Beachten Sie, dass die zurückgegebene Stringlänge nicht mit dem Argument size übereinstimmt (size != final length).

3. Krypto-Zufallswerte aus einer begrenzten Anzahl von Zeichen


Beachten Sie, dass bei dieser Lösung die erzeugte Zufallsfolge nicht gleichmäßig verteilt ist.

Sie können auch eine starke Zufallszeichenfolge aus einer begrenzten Anzahl von Zeichen wie dieser erstellen:

var crypto = require('crypto');

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

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

  const randomBytes = crypto.randomBytes(length);
  let result = new Array(length);

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

  return result.join('');
}

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

Beispiel für die Verwendung:

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

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

22voto

Inkling Punkte 3173

Ab Node.js 14.18 und 15.7 wird url-sichere base64-Kodierung unterstützt ist eingebaut :

const token = crypto.randomBytes(48).toString('base64url');

Wenn Sie die asynchrone Version verwenden möchten (weil die Funktion möglicherweise auf Entropie warten muss), kann sie besser mit modernen Mustern in Einklang gebracht werden:

const randomBytesAsync = util.promisify(crypto.randomBytes);

const token = (await randomBytesAsync(48)).toString('base64url');

21voto

real_ate Punkte 10020

Die aktuelle richtiger Weg um dies asynchron mit ES 2016 Standards von async und await (ab Node 7) zu tun wäre das folgende:

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

Dies funktioniert in Node 7 ohne jegliche Babel-Transformationen

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X