내맘대로 살기🎉

[Node.js] 비밀번호 보안 (md5, sha256, PBKDF2) 본문

개발자의 길/Node.js

[Node.js] 비밀번호 보안 (md5, sha256, PBKDF2)

해림😶 2017. 5. 27. 12:54


md5로 암호화를 하는 방법


1. md5방식의 해싱. (터미널에서 npm install md5 --save)

2. 터미널에서 node

3. var md5 = require('md5');

4. md5('javascript'); 를 검색해보면 암호화된 문자('de9b9ed78d7e2e1dceeffee780e2f919')를 출력한다. 

암호화를 푸는 것을 "복호화".

복호화가 불가능 한 것을 "단방향 암호화 방법"이라고 한다. md5가 단방향이다.

5. 터미널에서 md5('원래의 비밀번호');로 원래의 비밀번호를 암호화한 문자로 얻고 그 문자를 코드에 넣는다.  

6. 코드에서 사용자가 입력한 비밀번호도 md5(입력받은 비밀번호) 이렇게 묶어준다.


사용자가 입력한 비밀번호가 어떤 것인지 확인하는 것이 아니라, 사용자가 입력한 비밀번호가 가입할 때의 비밀번호와 같은지 비교만 하는 것이다. 


하지만, 구글에 md5 dictionary online 라고 검색하고 아무 사이트나 들어가서 md5로 암호화된 코드를 입력하면 복호화해준다... 너무 간단하게 뚫린다.



간단하게 뚫리지 않는 방법 (조금은 어렵게 뚫려보자.)


1. var salt = "29SJHCX*U@Y@*(HUDISA";

2. var pwd = '원래의 비밀번호';

3. md5(pwd + salt); 라고 하면, salt와 pwd를 더한 값이 암호화되기 때문에, 사이트에 가서 복호하를 하려고 해도 되지 않는다. 성공이다 !! 


사용자의 비밀번호에 "무엇"인가 추가해서 보안을 높이는 것이다. 그 "무엇"을 소금을 친다. 라고 표현한다고 한다.


그렇지만, 다른 사용자와 비밀번호가 같다면, 암호화된 문자도 같을 것이다. 그렇다면, 한 명의 비밀번호가 뚫리면, 모두 다 뚫린다는 것이다. 그리하여, 사용자마다 다른 salt를 선언해주어야 한다. 


하지만, 현대에는  md5가 보안에 취약하다고한다.. 



md5의 대안, "sha"를 사용하는 방법


md5보다 보안에 강하다고 하다.

1. npm install sha256 --save로 다운받자. (조금 더 보안을 원하면 sha512를 사용.)

그 후 사용법은 md5와 같다.



더욱 높은 보안, PBKDF2


링크에서 확인 가능하다. 링크에서 확인하면 알겠지만,

1
2
var bkfd2Password = require("pbkdf2-password");
var hasher = bkfd2Password();
cs

물론, npm install pbkdf2-password --save를 해서 다운받아야한다.


1
2
3
hasher({password:'111'}, function(err, pass, salt, hash){
    console.log(err, pass, salt, hash);
});
cs

위와 같이 실행해보면,


undefined '111' '4UCTS/Hii2KH0A361eEMgEdJZswI2lOMpmxiZekiYgb0L5ZFFQ96+S2REQp8qz9jzmP5zbwT/qRZWi/0HlJ9fQ==' 'UTzZd+G3k34z8LSoPU7iLtxmN6MbcNyU6ALsmTXzdv7QyZRKp2k02cFNiA8wG4tpGL6L6C8SaNqh1CcsVDyvhcf0pjatybUPAHkcqhO+YEGI5MjvfubNvx1oxZHEpIJ14uoNCbGeSNgBg1JXlzSPYSU0lcYBW8212j9TROY9H7o='


라고 나오는데, 각각 매개변수를 의미한다.

err - undefined 

pass - '111'

salt - '4UCTS/Hii2KH0A361eEMgEdJZswI2lOMpmxiZekiYgb0L5ZFFQ96+S2REQp8qz9jzmP5zbwT/qRZWi/0HlJ9fQ=='

hash - 'UTzZd+G3k34z8LSoPU7iLtxmN6MbcNyU6ALsmTXzdv7QyZRKp2k02cFNiA8wG4tpGL6L6C8SaNqh1CcsVDyvhcf0pjatybUPAHkcqhO+YEGI5MjvfubNvx1oxZHEpIJ14uoNCbGeSNgBg1JXlzSPYSU0lcYBW8212j9TROY9H7o='


위와 같이 자동으로 salt값과 hash값을 넣어준다. (실행 할 때마다 다르다.)


실제로 사용을 할 때, app.post에서 hasher()함수를 사용해야한다.

사용할 때, "hash"값 만으로는 비밀번호 값을 정확하게 가져올 수 없기 때문에 "salt"값을 꼭 같이 가져와야한다.



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
for(var i=0; i<users.length; i++){
    var user = users[i];
    if(uname === user.username){
        return hasher({password:pwd, salt:user.salt}, function(err, pass, salt, hash){
            if(hash === user.password){
                req.session.displayName = user.displayName;
                req.session.save(function(){
                    res.redirect('/welcome');
                });
            } else{
                res.send('Who are you ? <a href="/auth/login">login</a>');                
            }
        });
    }
}
cs

return hasher를 하는 이유는, for문이 빙글빙글 돌다가 res.send가 실행이 되고 난 뒤에 콜백함수가 실행된다. 그래서 hasher가 실행되는 순간에 함수의 실행을 끝내려고 return을 넣는다.


1
2
3
4
5
6
7
8
9
10
11
12
13
hasher({password:req.body.password}, function(err, pass, salt, hash){
    var user = {
        username: req.body.username,
        password: hash,
        salt:salt,
        displayName: req.body.displayName
    };
    users.push(user);
    req.session.displayName = req.body.displayName;
    req.session.save(function(){
        res.redirect('/welcome');
    });
});

cs

이 코드는 그냥 내가 참고하려고 넣었다.. 


참조 : 생활코딩 node.js Security - Password (비밀번호 보안)


반응형
Comments