programing

Node.js의 안전한 랜덤 토큰

itsource 2022. 9. 28. 23:33
반응형

Node.js의 안전한 랜덤 토큰

질문에서 에릭은 Node.js에서 안전한 랜덤 토큰을 생성해야 합니다.방법이 있다crypto.randomBytes랜덤 버퍼를 생성합니다.단, 노드의 base64 인코딩은 url-safe가 아닙니다./그리고.+대신-그리고._따라서 이러한 토큰을 생성하는 가장 쉬운 방법은

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

'hex' 인코딩은 노드 v0.6.x 이상에서 작동합니다.

JS 전문가가 아닌 경우 동기 옵션입니다.인라인 함수 변수에 액세스하는 방법에 대해 약간의 시간을 할애해야 했습니다.

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

1. nanoid 서드파티 라이브러리 사용 [NEW]


JavaScript용 작고 안전한 URL 친화적인 고유한 문자열 ID 생성기

https://github.com/ai/nanoid

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

2. 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 인수(크기!= 최종 길이)와 일치하지 않습니다.


3. 제한된 문자 집합의 암호 랜덤 값


이 솔루션에서는 생성된 랜덤 문자열이 균일하게 분포되지 않도록 주의하십시오.

다음과 같은 제한된 문자 집합에서 강력한 랜덤 문자열을 작성할 수도 있습니다.

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

사용 예:

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

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

ES 2016 비동기 및 대기 표준을 사용하여 비동기적으로 이를 수행하는 최신 방법은 다음과 같습니다(Node 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, '');

비동기/대기 및 프로미제이션 포함.

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

다음과 같은 것을 생성합니다.VjocVHdFiz5vGHnlnwqJKN0NdeHcz8eM

체크 아웃:

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

Node.js 14.18 및 15.7에서는 url-safe base64 인코딩 지원이 내장되어 있습니다.

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

비동기 버전을 사용하는 경우(함수가 엔트로피를 기다릴 필요가 있기 때문에), 최신 패턴에 보다 잘 맞도록 비동기 버전을 프로미스화할 수 있습니다.

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

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

crypto-module-string은 이를 위한 적절한 모듈입니다.

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)더하다.async사고 싶다면promise.

보다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 module anyid는 다양한 종류의 문자열 ID/코드를 생성할 수 있는 유연한 API를 제공합니다.

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

.random-token lib. 매우 사용하기 쉽습니다. :)

var randomToken = require('random-token').create('abcdefghijklmnopqrstuvwxzyABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789');
var token = randomToken(16);

그리고 당신은 다른 소금을 사용할 수 없습니다.

var randomToken = require('random-token');
var token = randomToken(16); // output -> d8d4kd29c40f021 ```

당신의 단말기에서 그냥 쓰세요.

node -e "console.log(crypto.randomBytes(48).toString('hex'))"

0 의존 관계가 없는 솔루션...브라우저, deno 및 nodej(새로운 글로벌 웹 암호화 사용)에서 작동

const random = size => btoa(
  String.fromCharCode(
    ...crypto.getRandomValues(
      new Uint8Array(size)
    )
  )
).replaceAll('+', 'x').replaceAll('/', 'I').slice(0, size)

for (let i = 5; i--;) console.log(random(16))

언급URL : https://stackoverflow.com/questions/8855687/secure-random-token-in-node-js

반응형