Computer >> 컴퓨터 >  >> 프로그래밍 >> JavaScript

Node.js crypto.randomBytes() 메서드 완벽 가이드 – 안전한 난수 생성 방법

crypto.randomBytes()는 암호학적으로 안전한(cryptographically strong) 의사 난수 데이터를 생성하는 Node.js 내장 메서드입니다. 이 메서드는 생성된 바이트에 충분한 엔트로피(entropy)가 확보될 때까지 작업을 완료하지 않지만, 실제로는 대기 시간이 몇 밀리초를 넘지 않으므로 성능상 부담 없이 사용할 수 있습니다.

생성된 무작위 바이트는 세션 토큰, 비밀번호 재설정 링크, API 키, 솔트(salt) 값 등 보안이 중요한 다양한 용도로 활용됩니다.

문법(Syntax)

crypto.randomBytes(size[, callback])

매개변수(Parameters)

  • size – 생성할 바이트 수를 지정합니다. 크기는 2**31 - 1(약 2GB)를 초과할 수 없으며, 이 값을 벗어나면 에러가 발생합니다.

  • callback – 선택적 매개변수로, 메서드 실행 중 오류가 발생하거나 난수 생성이 완료되었을 때 호출됩니다. 콜백은 (err, buf) 두 개의 인자를 전달받으며, 오류 발생 시 err에 에러 객체가 담기고, 정상 처리 시 buf에 생성된 버퍼가 담깁니다. 참고로 최신 Node.js 버전에서는 콜백을 생략하고 동기 방식으로 사용할 수 있습니다.

예제 1: 비동기(Asynchronous) 방식

먼저 randomBytes.js라는 이름의 파일을 생성하고 아래 코드를 복사해 붙여넣습니다. 이후 다음 명령어로 코드를 실행할 수 있습니다.

node randomBytes.js

randomBytes.js

// crypto.randomBytes() 비동기(Asynchronous) 예제

// crypto 모듈 가져오기
const crypto = require('crypto');

crypto.randomBytes(64, (err, buf) => {
    if (err) throw err;
    console.log(`${buf.length} bytes of random data: ${buf.toString('hex')}`);
});

출력 결과

C:\home\node>> node randomBytes.js
64 bytes of random data:
eb2bcebb999407286caea729998e7fa0c089178f8ca43857e73ea3ff66dbe1852af24a4b0199be
9192798a3f8ad6d6475db3621cfacf38dcb0fba5d77d73aaf5

위 예제에서는 64바이트의 난수를 생성한 후 toString('hex')를 사용해 16진수 문자열로 변환하여 출력했습니다.

예제 2: 동기(Synchronous) 방식

이번에는 콜백 없이 동기적으로 난수를 생성하는 예제를 살펴보겠습니다.

// crypto.randomBytes() 동기(Synchronous) 예제

// crypto 모듈 가져오기
const crypto = require('crypto');

const buffer = crypto.randomBytes(256);
console.log(
    `${buffer.length} bytes of random data: ${buffer.toString('base64')}`);

출력 결과

C:\home\node>> node randomBytes.js
256 bytes of random data:
n7yfRMo/ujHfBWSF2VFdevG4WRbBoG9Fqwu51+/9ZBUV6Qo88YG7IbcEaIer+g+OgjMv4RyNQ6/67a
F5xWmkOR3oA6J6bdAJ1pbstTuhIfItF1PQfP26YXk1QlaoKy/YJxPUngyK4kNG9O04aret4D+2qIq9
BUaQcv+R9Xi014VKNUDZ+YQKEaLHBhJMq6JgehJ56iNbdNJ4+PN7SQwjNdZ8gS76izAwYsSZ7Kuyx2
VzdXIKsLmjleuJ2DZ7/6Yyn8WM9463dhuh0KQ5nwFbgzucvjmdvDjBlGFZBGlKs6AXqYh+0Oe6Ckkv
3OpnXOJs+GExbmnvjaeDQ03khpdJfA==

동기 방식은 반환값으로 직접 Buffer 객체를 받기 때문에 코드가 더 간결하지만, 대용량 난수를 생성할 경우 이벤트 루프를 잠시 차단할 수 있다는 점을 유의해야 합니다. 따라서 서버 환경에서는 일반적으로 비동기 방식 또는 util.promisify()를 활용한 Promise 패턴 사용이 권장됩니다.