Sécurisez le jeton aléatoire dans le noeud.js
Dans cette question Erik doit générer une sécurité aléatoire jeton dans le Nœud.js. Il y a la méthode crypto.randomBytes
qui génère un tampon aléatoire. Cependant, l'encodage base64 dans le noeud n'est pas sûr pour les URLs, il inclut /
et +
au lieu de -
et _
. Par conséquent, la façon la plus facile de générer un tel token que j'ai trouvé est
require('crypto').randomBytes(48, function(ex, buf) {
token = buf.toString('base64').replace(///g,'_').replace(/+/g,'-');
});
Est-il un moyen plus élégant?
11 réponses
Essayer crypto.randomBytes() :
require('crypto').randomBytes(48, function(err, buffer) {
var token = buffer.toString('hex');
});
Le 'hex' encodage travaille dans le nœud v0.6.x ou plus récent.
option synchrone au cas où vous ne seriez pas un expert JS comme moi. A dû passer un certain temps sur la façon d'accéder à la variable de fonction en ligne
var token = crypto.randomBytes(64).toString('hex');
0. Utilisation de nanoid third party library [nouveau!]
un petit, sécurisé, URL-friendly, générateur d'ID de chaîne unique pour JavaScript
const nanoid = require("nanoid");
const id = nanoid(48);
1. Codage en Base 64 avec l'URL et le nom de fichier en Sécurité de l'Alphabet
page 7 de RCF 4648 décrit comment encoder en base 64 avec la sécurité des URL. Vous pouvez utiliser une bibliothèque existante comme base64url pour faire le travail.
la fonction sera:
var crypto = require('crypto');
var base64url = require('base64url');
/** Sync */
function randomStringAsBase64Url(size) {
return base64url(crypto.randomBytes(size));
}
exemple d'utilisation:
randomStringAsBase64Url(20);
// Returns 'AXSGpLVjne_f7w5Xg-fWdoBwbfs' which is 27 characters length.
notez que la longueur de la chaîne retournée ne correspondra pas à l'argument Taille (size != longueur finale).
2. Valeurs aléatoires Crypto à partir d'un jeu limité de caractères
méfiez-vous qu'avec cette solution la chaîne aléatoire générée n'est pas distribuée uniformément.
vous pouvez aussi construire une chaîne aléatoire forte à partir d'un ensemble limité de caractères comme celui-ci:
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');
}
exemple d'utilisation:
randomAsciiString(20);
// Returns 'rmRptK5niTSey7NlDk5y' which is 20 characters length.
randomString(20, 'ABCDEFG');
// Returns 'CCBAAGDGBBEGBDBECDCE' which is 20 characters length.
L'up-to-date droit chemin", 151930920" pour ce faire de manière asynchrone à l'aide de ES 2016 normes de async et await (Nœud 7) serait la suivante:
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);
}
cela fonctionne hors de la boîte dans le noeud 7 sans aucune transformation Babel
Aléatoire URL et le nom de la chaîne de sécurité (1 conduit)
Crypto.randomBytes(48).toString('base64').replace(/\+/g, '-').replace(/\//g, '_').replace(/\=/g, '');
regardez real_ates
es2016 way, c'est plus 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'));
};
Générateur/Rendement Moyen
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'));
});
Check out:
var crypto = require('crypto');
crypto.randomBytes(Math.ceil(length/2)).toString('hex').slice(0,length);
With async / wait and promisification .
const crypto = require('crypto')
const randomBytes = Util.promisify(crypto.randomBytes)
const plain = (await randomBytes(24)).toString('base64').replace(/\W/g, '')
génère quelque chose de similaire à VjocVHdFiz5vGHnlnwqJKN0NdeHcz8eM
Voici une version asynchrone tirée mot à mot de la réponse de @Yves M.
var crypto = require('crypto');
function createCryptoString(length, chars) { // returns a promise which renders a crypto string
if (!chars) { // provide default dictionary of chars if not supplied
chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
}
return new Promise(function(resolve, reject) {
var charsLength = chars.length;
if (charsLength > 256) {
reject('parm chars length greater than 256 characters' +
' masks desired key unpredictability');
}
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];
}
resolve(result.join(''));
});
}
// --- now generate crypto string async using promise --- /
var wantStringThisLength = 64; // will generate 64 chars of crypto secure string
createCryptoString(wantStringThisLength)
.then(function(newCryptoString) {
console.log(newCryptoString); // answer here
}).catch(function(err) {
console.error(err);
});
le module npm anyid fournit une API flexible pour générer divers types d'ID / code de chaîne.
pour générer une chaîne aléatoire dans A-Za-z0-9 en utilisant 48 octets aléatoires:
const id = anyid().encode('Aa0').bits(48 * 8).random().id();
// G4NtiI9OYbSgVl3EAkkoxHKyxBAWzcTI7aH13yIUNggIaNqPQoSS7SpcalIqX0qGZ
pour générer une chaîne d'alphabet de longueur fixe uniquement remplie par des octets aléatoires:
const id = anyid().encode('Aa').length(20).random().id();
// qgQBBtDwGMuFHXeoVLpt
interne il utilise crypto.randomBytes()
pour générer aléatoire.
https://www.npmjs.com/package/crypto-extra a une méthode pour cela :)
var value = crypto.random(/* desired length */)