배포 준비 첫 번째 글이다.

 

배포 전에 보안 처리를 해야하는 데 나는 어차피 GIT에 모든 코드가 올라가있기 때문에 보안 상 다 뚫려있지만 실제 상업용 사이트를 배포하는 것처럼 세팅을 해놓을 것이다.

 

그 동안은 회원가입/로그인 기능 테스트를 위해 패스워드를 암호화하지 않았지만, 이제 배포를 앞두고 보안 처리를 해야 한다.

 

먼저 패스워드를 암호화해서 저장하고 로그인 시 암호화 된 문자열을 비교해 회원 가입 여부를 판단할 수 있도록 구현할 것이다. 

 

 

참고한 사이트

 

여기는 암호화의 종류와 개념을 이해하기 쉽게 설명되어 있다.

 

(NodeJS) crypto 모듈을 사용한 암호화

안녕하세요. 이번 시간에는 crypto 모듈을 사용해서 비밀번호를 암호화하는 방법에 대해 알아보겠습니다. 예전 패스포트 강좌에서는 패스포트 기능 설명에 중점을 두었기 때문에 비밀번호는 그

www.zerocho.com

 

여기는 실제로 코드에 구현할 때 참고하기 좋다.

 

Node 내장 암호화 모듈 Crypto

Node.js를 설치하게 되면 내장 모듈중 crypto라는 모듈이 있습니다. 이 모듈을 사용하여 암호화 하는 방법...

blog.naver.com

 

두 사이트 모두에서 코드를 참고했다.

 

 

 

 

패스워드 암호화해서 DB에 저장하기

 

사실 암호화하는 코드는 참고한 사이트에서 보면 생각보다 짧아서 어렵지 않구나 하고 생각했는데 salt를 어떻게 저장해야 하는 가에서 약간 헤맸다.

 

구글링을 해보면 salt는 돌릴 때마다 값이 달라지니 로그인 기능을 구현하려면(동일 값 여부 확인) 하려면 암호화 할 당시의 salt 값이 필요하고(사용자마다 고유한 salt 값 가짐) 그러려면 어딘가에는 저장해야 한다고 나와 있었다.

 

근데 저장해야 한다면 DB가 제일 먼저 생각났는데 DB에 암호화된 패스워드랑 salt 값을 같이 저장하면 암호화한 의미가 없어지지 않나? 라는 생각이 들어서 망설여졌다.

 

게다가 DB에 저장하는 경우도 찾아봤는데 그냥 암호화 개념 설명을 편하게 하기 위해 DB에 저장하는 듯한 느낌이어서 DB에 저장해도 되나 라는 생각이 들었다.

 

그런데 다시 생각해보면 패스워드를 암호화하는 이유는 DB가 해킹 당했을 때 패스워드를 알아보지 못하게 하기 위함이고 그러면 DB에 암호화된 패스워드와 salt 값을 같이 넣어도 어떤 방식으로 암호화했는 지는 DB가 아니라 코드에 나와있기 때문에 같이 저장해도 되는 거 아닐까 라는 생각이 들었다.

 

그래서 나는 일단 DB에 salt 값을 같이 저장했다.

 

var password = request.body.password;
      crypto.randomBytes(64, (err, buf) => {
        const salt = buf.toString('base64')
        crypto.pbkdf2(password, salt, 107529, 64, 'sha512', (err, key) => {
          User.create ({  //DB 생성
            id:request.body.id,
            password:(key.toString('base64')),
            salt : salt,
            name:request.body.name,
            phone:request.body.phone,
          }); 
        });
      });

 

 

 

암호화한 패스워드 값 비교하기(로그인)

 

사용자가 입력한 id 값으로 DB에서 사용자를 찾고 DB에 같이 저장된 salt 값을 가져와서 동일한 방식으로 암호화해서 패스워드 동일 유무를 확인하는 방식으로 코드를 작성했다.

 

  User.findOne({id : req.body.id},(err, users) => {  // id를 먼저 체크해서
    if(!users || err){ //id가 DB에 없으면(즉, id가 틀렸거나 회원가입이 안되어 있거나) 
      res.redirect('/login');
    }
    else {
    var cpassword = req.body.password;  // 사용자가 입력한 패스워드를 가져와서
    crypto.randomBytes(64, (err, buf) => {
      crypto.pbkdf2(cpassword, users.salt, 107529, 64, 'sha512', (err, key) => {
        cpassword = key.toString('base64')  // DB에 저장했던 동일한 방식으로 암호화 
        
        if (users.password == cpassword) {  // 저장된 패스워드와 암호화된 입력받은 패스워드 비교
          res.cookie('session', users.name, {
          maxAge : 6000000 // 쿠키 1시간 유지
        });
      res.redirect('/');
        }
      });
    });
  }
  })

 

 

 

저장된 DB