javascript 에서 crypto로 랜덤 키 만들기 (base64, 버퍼 개념 등)
자바스크립트에서 랜덤 키가 필요할 때가 있다. 간단한 암호화나 다른 목적으로 키가 필요할 때가 있기 때문이다. 그럴 때 노드 (node) 에 내장된 crypto 함수로 쉽게 값들을 생성할 수 있다.
일단 암호화에 "aes-256-cbc" 알고리즘을 사용하고 있다고 가정해 보자. 이 알고리즘은 256bit의 키가 필요하다. 8비트가 1바이트 이므로 256bit는 32바이트의 문자열이 필요하다.
가장 기본적으로는 crypto.randomBytes(32) 로 32 바이트의 버퍼를 생성할 수 있다. 이걸 hexadecimal (16진수) 로 바꿔서 문자로 표시하면 된다.
node 명령어에서 다음을 입력해 보자.
const crypto = require("crypto");
const key = crypto.randomBytes(32).toString("hex");
console.log(key);
// '33af1236d909773b02a703c77a260ec0a766665a77f2d3e0672809c3ec6cc7ce'
이렇게 하면 32비트의 16진수가 나오게 된다. 그런데 16진수는 소문자 a-f와 숫자 0-9만으로 이루어진 문자열이라서 만족스럽지 않다. 그래서 대문자나 전체 알파벳이 나오게 base64로 encoding 해보았다.
const crypto = require("crypto");
const key = crypto.randomBytes(32).toString("base64");
console.log(key);
'7pTPum2oKq6U+kXihI5NLJZ5JorXSVaeBDgf6C+o3Yc='
이렇게 하면 랜덤 문자 숫자가 나온다. 끝에 = 가 나오는데 이건 base64는 영문 4글자를 3 bytes로 묶는데 끝에 2바이트가 들어간게 있으면 패딩 (padding) 형식으로 = 를 넣는다.
물론 정말 중요한 패스워드나 암호화는 모든 문자와 특수문자가 다 나오는 방식으로 하는게 가장 좋다.
Strong Random Password Generator 와 같이 복잡한 암호를 생성해주는 사이트도 있다.
base64란?
binary를 text로 인코딩해주는 방법이다. 64개의 문자와 맵핑되며 이 문자는 대소문자의 알파벳과 숫자 0-9, 그리고 기호 +와 / 가 포함된다. 바이너리 데이터를 텍스트 포맷으로 나타낼 때 사용된다. 예를 들면 HTML에 이미지를 임베딩 할 때 사용된다.
바이너리 데이터란?
0과 1로 이루어진 데이터 배열이다. 보통 8개로 묶어서 1 바이트로 표현한다. 컴퓨터가 읽을 수 있다. 모든 텍스트, 이미지, 오디오, 비디오는 이 바이너리 데이터 (2진수) 로 이루어져 있다.
// 예시
01101000 01100101 01101100 01101100 01101111
노드에서 버퍼 (Buffer) 란?
바이너리 데이터를 메모리에 올려 다룰 수 있게 해주는 글로벌 객체이다. 이를 통해 바이너리 데이터를 효과적으로 다룰 수 있다. (원래 컴퓨터 과학에서 버퍼란 데이터를 처리하기 위한 임시 저장소를 의미한다. 이 버퍼를 통해 데이터를 더 작은 chunk (덩어리)로 처리할 수 있다.
const buf = Buffer.from('hello world');
console.log(buf); // outputs <Buffer 68 65 6c 6c 6f 20 77 6f 72 6c 64>
console.log(buf.toString()); // outputs 'hello world'
이렇게 보면 hello world 라는 문자가 버퍼 형식으로 바뀐 것을 알 수 있다. Buffer 내에서는 16진수로 바뀌어서 기계가 읽기 쉬운 형태로 바뀌었다! (예전에 게임을 해킹해 보신 분들이라면 아실려나...)
데이터의 크기 단위
1 바이트 = 8비트
1 킬로바이트(KB) = 1,024 바이트
1 메가바이트(MB) = 1,024 킬로바이트
1 기가바이트(GB) = 1,024 메가바이트
1 테라바이트(TB) = 1,024 기가바이트
어렸을 때 외우고 다니던 데이터의 크기 단위이다. 알아두면 상식적인 면에서 매우 좋을 것 같다!