사용자의 비밀번호를 그대로 DB에 저장하면 엄청난 보안 취약점이 된다 (하면 안된다)
문자열을 되돌릴 수 없는 방식으로 암호화하여, hash 출력값을 이용해 사용자의 비밀번호를 알아낼 수 없다 (= 복호화가 불가능하다 )
단방향 암호화 방법으로 비밀번호를 잊어버렸을 때, 다시 알려주지 않고 비밀번호 재설정을 하게 되는 이유이다
로그인 시 전달된 비밀번호의 Hash 값과 DB에 저장된 값을 비교하여 로그인을 처리한다
const hash = crypto.createHash('sha1'); //사용할 hash 알고리즘 설정
hash.update(password); //변환할 문자열_password를 'sha1'알고리즘으로 해싱
hash.digest("hex"); //인코딩할 알고리즘 입력 -> 변환된 문자열을 반환한다
Node.js의 기본제공 모듈인 crypto모듈을 사용해 hash값을 얻을 수 있다
sha1 알고리즘 외에도 더 강력한 sha224, sha256 등의 알고리즘이 있다
hasing이 완료된 암호화된 데이터를 다이제스트(digest)라고 한다
동일한 비밀번호에 대해 동일한 값을 갖는다
https://www.convertstring.com/ko/Hash/SHA256
qwerty1234 라는 문장에 대해 계속 해서 생성을 해도 동일한 값(digest)만이 출력된다
해시 함수에 대한 입력값-출력값을 저장해 놓는 레인보우 테이블(Rainbow Table)을 통해 역으로 hashing 이전의 비밀번호를 알아낼 수도 있다 (무차별 대입 공격도 가능하다)
레인보우 테이블(Rainbow Table)을 만들기 어렵게 하자
Hashing시에 Salt를 뿌려 비밀번호를 복호화 하는 것을 방해하는 방법
사용자의 기본 비밀번호에 추가 문자열(Salt)를 더해 Hashing하는 방식이다
동일한 비밀번호를 가진 2명의 사용자끼리도 추가된 문자열(Salt)로 인해 다른 Hash값을 갖게 된다
다른 한 명의 비밀번호가 유출되더라도 다른 사용자는 안전할 수 있다
ex) 사용자A, B의 비밀번호 : 1234
동일한 비밀번호에 대해 DB에 저장되는 digest를 비교해보면
동일한 비밀번호라도 salt값이 다르기 때문에 더 안전하게 될 수 있다
Salt값의 경우
각 사용자 별로 고유의 값을 암호화 최초에 설정되도록 하고 로그인 시를 위해 해당 salt값을 잘 갖고 있어야 한다 (DB저장)
Salt의 길이가 32byte 이상이어야 Salt와 digest를 추측하기 어렵다
비밀번호를 Hashing하는 과정을 반복하는 것이다
adaptive key derivation function은 다이제스트를 생성할 때 솔팅과 키 스트레칭을 반복하며
솔트와 패스워드 외에도 입력 값을 추가하여 공격자가 쉽게 다이제스트를 유추할 수 없도록 하고
보안의 강도를 선택할 수 있다
adaptive key derivation function 중 주요한 key derivation function은 다음과 같다
즉, 안전한 패스워드 저장을 위한 암호화 방법으로는 위의 세가지인 pbkdf, scrypt, bcrypt가 있다는 의미이다
DIGEST = PBKDF2(PRF, Password, Salt, c, DLen)
// PRF: 난수(예: HMAC)_해시함수(sha256..)
// Password: 패스워드
// Salt: 암호학 솔트
// c: 원하는 iteration 반복 수
// DLen: 원하는 다이제스트 길이
bcrypt.hashpw(password, bcrypt.gensalt())
DIGEST = scrypt(Password, Salt, N, r, p, DLen)
// Password: 패스워드
// Salt: 암호학 솔트
// N: CPU 비용
// r: 메모리 비용
// p: 병렬화(parallelization)
// DLen: 원하는 다이제스트 길이
MD5, SHA-1, SHA-256, SHA-512 등의 해시 함수는 메시지 인증과 무결성 체크를 위한 것이다
이것을 패스워드 인증을 위해 사용하면 (인식 가능성과 빠른 처리 속도에 기인하는) 취약점이 존재한다
이를 해결하기 위해서는 위에서 언급한 key derivation function을 사용하는 것을 권장한다
[NODE] 📚 crypto 모듈 (단방향 / 양방향) 암호화 원리 & 사용법
[NODE] 📚 bcrypt 모듈 암호화 원리 & 사용법
Naver D2_안전한 패스워드 저장
안전한 패스워드 만드는 방식
안전한 패스워드 보안(패스워드 암호화 저장법 /bcrypt, scrypt, pdkdf2 )
패스워드의 암호화와 저장 - Hash(해시)와 Salt(솔트)
Node.js :: Bcrypt로 비밀번호 해싱(Hashing)하기