지난번 계산기 만들기 이후에 정보처리기사 실기 시험을 보느라 실시간 채팅 프로그램 개발을 진행하지 못하였는데
어제(5월 7일) 실기 시험이 종료가 되어 드디어 시작할 수 있게 되었습니다(결과는 한 달 뒤에 나오니.. 차분하게 기도해야될꺼같아요..)
채팅 프로그램에 회원가입 로직 개발 중 패스워드 암호화 관련하여 crypto라는 모듈이 있어 내용 정리합니다
이전에 주로 php에서 개발을 진행했을 때는 password_hash 함수에 salt값을 추가해서 암호화를 진행하였는데 Nodejs에서도 동일하게 진행해보도록 하겠습니다
단방향 암호화
단방향 암호화란 일반적인 평문을 암호화했을 때 암호화가 된 문자열을 복호화할 수 없는 암호화 알고리즘입니다
암호화를 진행할 시 주로 해시 알고리즘을 사용하며 대표적으로 MD5, SHA-1, SHA-256 등 다양한 해시 알고리즘이 존재합니다
이러한 구조를 사용해 주로 유저에 비밀번호를 암호화할 때 많이 사용합니다, 유저에 비밀번호 같은 경우는 사용자 본인 외에는 비밀번호를 몰라야 되기 때문에 사이트 공격(해킹)을 당했을 경우에도 해커가 비밀번호를 복호화할 수 없기에 많이 사용합니다
단방향 암호화에 문제점
단방향 암호화에 문제점은 해시 알고리즘을 사용을 했기 때문에 동일한 문자열은 동일한 암호 화문을 사용합니다
이러하면 해커가 동일한 해시값을 담을 테이블을 사용하여 사용자의 비밀번호를 충분히 유추가 가능하여 문제가 발생하며, 이를 해결하기 위해 단방향 암호화 사용 시 salt값을 같이 사용합니다
Salt
단어 뜻 그래도 소금이라는 의미를 담고 있으며 암호화된 해시 문에 추가적으로 입력하는 랜덤 데이터입니다
이러한 salt값이 추가가 되면 해시값 + salt값까지 유추를 해야 되기 때문에 해커는 엄청나게 많은 데이터를 유추를 해야 됩니다
암호화 구현
그러면 본격적으로 Node js에서 Crypto모듈을 사용하여 암화화를 구현해보도록 하겠습니다
crypto 모듈 같은 경우는 nodejs 내장 함수 이므로 별도에 npm install로 설치할 필요는 없습니다
Encryption 클래스 생성
const crypto = require('crypto');
class Encryption {
constructor() {
}
}
module.exports = Encryption;
Encryption이라는 클래스를 생성하고 crypto 모듈을 추가하였습니다
Salt 생성 함수 추가
/**
* @description salt값 생성
* @returns salt
*/
async createRandomSalt(){
return new Promise((resolve,reject)=>{
crypto.randomBytes(64,(err,buf)=>{
if(err){
reject(err);
}else{
resolve(buf.toString("hex"));
}
})
})
}
salt값을 생성하는 함수입니다, randomBytes가 비동기식으로 구동이 되고 있어서 async 함 와 Promise를 사용해서 구현하였으며,
reandombytes에서 나온 값을 16진수 문자열 형태로 리턴해줍니다
createRandomSalt 함수 호출 시 아래와 같은 salt값 출력을 확인할 수 있습니다
createPassword 함수 추가
/**
*
* @param {*} userPassword
* @returns password
*/
async createPassword(userPassword){
let salt = await this.createRandomSalt();
console.log("Salt : ",salt);
return new Promise((resolve,reject)=>{
//키스트림 100번반복
crypto.pbkdf2(userPassword,salt,100,64,"sha512",(err,key)=>{
if(err){
reject(err)
}else{
resolve(key.toString("hex"));
}
})
})
}
문자열을 입력받아 평문을 암호화하는 함수입니다
위에서 추가했던 createRandomSalt값을 호출해 우선 salt값을 얻어낸 후
crypto 모듈에 pbkdf2 함수를 이용해 암호화를 진행합니다, 해당 함수 파라미터로는 평문 값, salt값, 키스 트림 반복 값, 비트 값 이렇게 들어가 게 되어있는데 여기서 키스 트립 반복 값 같은 경우는 입력한 값만큼 해시 알고리즘을 돌리겠다는 의미입니다
해당 함수를 호출하면 아래와 같은 결과가 나옵니다(userPassword "abc" 입력)
솔트 값, 암호화 값 모두 잘 나오는 것을 확인할 수 있으며 해당 값을 DB에 저장해주면 암호화는 완료됩니다
마치며
오늘은 Nodejs에서 암호화를 작업해보았는데 이전에 php로 개발했을 때와는 사뭇 다른 경험이었고 단방향 암호화와 salt값을 더 자세히 알 수 있었던 거 같습니다, 다음 작업으로는 DB에 저장된 암호문과 Salt값을 사용해서 실제 로그인하는 로직을 진행해보도록 하겠습니다
'javascript' 카테고리의 다른 글
Node Js,Vue - SocketIo 세팅 (0) | 2022.05.22 |
---|---|
Node JS JWT Token (0) | 2022.05.14 |
Node js Crypto 모듈 로그인 (0) | 2022.05.11 |
eval 함수 없이 계산기 만들기-2일차 (0) | 2022.04.10 |
eval 함수 없이 계산기 만들기-1일차 (0) | 2022.04.09 |