해시(Hash)와 Crypto 모듈

Node.js에서 사용하는 내장 모듈 중 하나인 Crypto 모듈에 대해 공부 하다가
해시(Hash)에 대해 좀 더 찾아보고 정리했다.


🧐 해시(Hash)란?

해시 함수(Hash Function) 또는 해시 알고리즘을 이용해 고정된 길이의 문자열로 바꾸는 것을 의미한다.

- 해시 함수 (Hash Function) : 임의의 길이의 데이터를 고정된 길이의 데이터로 매핑
- 키 (Key) : 매핑 전 원래 데이터의 값
- 해시 값 (Hash Value) : 매핑 후 데이터의 값
- 해싱 (Hashing) : 매핑 하는 과정

image

위 그림과 같이 비밀번호를 암호화할 수 있는데, 해시는 단방향 암호화 기법으로 복호화 할 수 없다. (다만 몇 가지 암호화 알고리즘은 뚫렸다고.. MD5나 SHA1 방식은 절대 네버 사용 금지)

복호화 : 암호화된 문자열을 다시 원래 문자열로 돌려놓는 것

즉, 사용자가 웹 사이트에 가입하면 서버는 사용자의 비밀번호를 해시 값으로 저장하고, 서버에는 사용자 비밀번호의 원본이 남지 않는다.

해시 알고리즘은 특정 입력에 대해 항상 같은 값을 반환하기 때문에 사용자가 로그인하면 비밀번호를 해시화 해 비교할 수 있다.

참고!
원본 문자열이 조금이라도 다르면 해시 형태가 굉장히 많이 달라진다. 이를 눈사태 효과 또는 쇄도 효과(avalanche effect)라고 한다.


🔐 Crypto 모듈로 해시를 사용해 보자.

(1) 기본적인 사용

var crypto = require('crypto');

var shasum = crypto.createHash('sha512');
shasum.update('PASSWORD');
var output = shasum.digest('hex');

// 한 번에 써도 됨!
//var output = crypto.createHash('sha512').update('PASSWORD').shasum.digest('hex');

console.log('PASSWORD : ', output);

입력은 길이 제한 없이 무한정으로 만들 수 있지만, 해시 값은 항상 고정된 길이의 값으로 나타내기 때문에 다른 입력이 같은 해시 값으로 나오는 경우가 있을 수 있다. (해시 충돌이 일어날 수 있다.)

(2) 솔트(salt) 사용하기

최근에는 해커들이 “A의 해시 값이 B다.”를 알고 있어 보안에 좀 더 신경 써야만 한다.

그렇게 정리 해둔 데이터베이스를 레인보우 테이블이라고 한다.

유출 피해를 최소화 하기 위해 비밀번호에 솔트(salt)라는 특정 값을 넣거나, 해시 함수를 여러 번 수행 하거나, 수행 횟수를 다르게 하는 등의 방법을 사용하는 것이 좋다.

crypto.randomBytes(64, (err, buf) => {
  crypto.pbkdf2('PASSWORD', buf.toString('hex'), 100000, 64, 'sha512', (err, key) => {
    console.log(key.toString('hex'));
  });
});

위 방법은 솔트를 사용하면서 해시 함수를 반복 수행하도록 했다.
주의할 점은 randomBytes( )가 매번 다른 솔트 값을 뱉어내기 때문에 솔트를 비밀번호(key)와 함께 저장해야 한다.

crypto.pbkdf2('입력비밀번호', '기존salt', 100000, 64, 'sha512', (err, key) => {
  console.log(key.toString('hex') === '기존 비밀번호');
});

이렇게 솔트 값, 반복 횟수, 비밀번호 길이, 해시 알고리즘, 인코딩 방식 모두 같아야 같은 값으로 인식한다.


해킹 수법이 진화하는 것처럼 암호화 기법도 진화하고 있다고 한다.
다음에 다른 암호화 기법들도 찾아봐야겠다.


📚 참고

모던 웹을 위한 Node.js 프로그래밍 (저자:윤인성)
https://ko.wikipedia.org/wiki/해시_함수
https://medium.com/@yeon22/crypto-해시-hash-란-6962be197523
https://www.zerocho.com/category/NodeJS/post/593a487c2ed1da0018cff95d

Joie-Kim

Joie-Kim

배운 것을 기록하는 습관! ✍️

comments powered by Disqus
rss facebook twitter github gitlab youtube mail spotify lastfm instagram linkedin pinterest medium vimeo stackoverflow reddit quora quora