ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [NodeJS] crypto Module을 이용한 단방향 암호화
    Framework/NodeJS 2021. 7. 20. 19:02
    crypto란 무엇일까?

     

    • 문자열을 암호화, 복호화, 해싱할 수 있도록 도와주는 모듈입니다
    • crypto 를 사용하여 Javascript 를 사용하는 웹 서비스에서 사용자의 정보를 안전하게 지킬 수 있습니다

     

    * 해시(Hash) 

    단방향 암호화 기법으로 해시함수, 해시 알고리즘을 이용해서 고정된 암호화 된 문자열로 바꿔줍니다

     

    * 해시 함수 

    임의의 길이의 데이터를 고정된 길이의 데이터로 매핑하는 함수입니다.

    매핑 전 원래 데이터 값을 key, 매핑 후 데이터의 값을 해시 값 이라고 합니다. 그리고 매핑하는 과정을 해싱이라고 합니다

     

     

    암호화 방식

     

    1. 단방향 암호화 : 복호화를 할 수 없는 암호화 방식입니다. 
    2. 양방향 암호화 : 복호화가 가능한 암호화 방식입니다. 

     

    * 복호화 

    암호화 된 문자열을 원래대로 되돌리는 방법입니다

     

    * 복호화가 필요하지 않은 이유 

    요새 피씨방이나, 앱, 홈페이지 등에서 비밀번호를 까먹으면 비밀번호를 찾는게 아닌, 비밀번호를 다시 생성하는 경우가 많습니다. 잘 생각해보면 사용자의 비밀번호는 복호화 할 필요가 없습니다. 왜냐하면 비밀번호를 암호화해서 DB에 저장해둔 후, 나중에 로그인할 때, 다시 입력받은 비밀번호를 같은 알고리즘으로 암호화해서 DB에 저장된 문자열과 비교하면 됩니다. 따라서 원래 비밀번호는 아무데도 저장되지 않고, 암호화된 문자열을 통해서만 비교하면 되는 것입니다.

     

     

    해시 함수를 이용한 단방향 암호화

     

    우선 crypto 모듈이 다운되지 않았을 경우 npm 을 이용해서 다운해줍니다

     

    npm install crypto --save

     

    다운이 됐다면 crypto 모듈을 불러와 해시 함수를 이용해 간단한 암호화를 해봅시다

     

    const crypto = require('crypto')
    const hashedPw = crypto.createHash('sha512').update('123456789').digest('base64');
    console.log(hashedPw)

     

    createHash 메소드에는 알고리즘 방식, update 메소드에는 비밀번호, digest 메소드에는 인코딩 방식을 인자로 넣어주면 됩니다 

     

    * 암호화 알고리즘 방식 :  sha256, sha512 ... (sha512 가 길지만 안전하기에 더 선호한다고 합니다)

    * 인코딩 방식 :  base64, hex, latin1 ... (base64 가 길이가 짧기 때문에 많이 선호한다고 합니다)

     

    하지만 위와 같은 해시만 사용한 암호화 방식은 절대로 사용하면 안됩니다!!

    왜냐하면 동일한 인코딩 방식과 알고리즘으로 비밀번호를 암호화 한 결과가 동일하여 DB가 해킹 당할 경우 이를 통해  비밀번호 유추가 가능하기 때문입니다.

     

    같은 비밀번호로 암호화 CODE

     

    동일한 결과 예제

     

    그렇다면 어떻게 해야될까? 비밀번호에 소금을 치는 것입니다.

    salt라는 특정 값을 통해서 위에서 나온 결과를 계속해서 변형할 수 있습니다. 비밀번호에 salt 문자열을 붙여 계속해서 해시와 하는 것입니다.

     

     

    Salt + Hash 를 이용한 단방향 암호화

     

    우선 salt 문자열을 생성해봅시다.

    const salt = crypto.randomBytes(32).toString('base64')

     

    문자열의 randomBytes 메소드에 문자열의 size를, toString 메소드에 인코딩 방식을 인자로 넣어주면 됩니다.

    그리고 아래의 코드와 같이 pbkdf2Sync를 이용해서 비밀번호와 salt를 붙여 암호화 해줍니다.

     

    const hashedPw = crypto.pbkdf2Sync('12345678', salt, 1, 32, 'sha512').toString('base64')

     

    pbkdf2Sync 메소드에는 비밀번호, salt 값, 반복 횟수, 길이, 암호화 방식을 인자로 넣어주고, toString 메소드에 인코딩 방식을 인자로 넣어주면 됩니다.

     

     

    • 전체코드

     

    const crypto = require('crypto')
    const salt = crypto.randomBytes(32).toString('base64')
    const hashedPw = crypto.pbkdf2Sync('12345678', salt, 1, 32, 'sha512').toString('base64')
    console.log(`salt : ${salt} , hashedPW1: ${hashedPw}`)

     

    CODE

     

    결과

     

    결과를 확인해보면 위와 같이 같은 비밀번호지만 암호화는 다르게 된 것을 확인할 수 있습니다.

    DB 에는 salt 값과 암호화 된 비밀번호를 저장해줘야 합니다.

     

    로그인을 할 때는 DB 에서는 저장된 salt 값암호화 된 비밀번호,  그리고 DB에 저장된 salt 값사용자가 입력한 비밀번호를 동일한 방식으로 암호화하여 비교하여 같다면 로그인, 아닐 경우 실패 이런식으로 처리하면 됩니다.

     

    로그인 인증 방법

     

     

     

     

     

     

     

    참고 자료

    https://velog.io/@neity16/NodeJS-crypto%EB%8B%A8%EB%B0%A9%ED%96%A5-%EC%95%94%ED%98%B8%ED%99%94

    https://www.zerocho.com/category/NodeJS/post/593a487c2ed1da0018cff95d

    https://medium.com/@yeon22/crypto-%ED%95%B4%EC%8B%9C-hash-%EB%9E%80-6962be197523

    https://devlog-wjdrbs96.tistory.com/164

    'Framework > NodeJS' 카테고리의 다른 글

    [Yarn] Node Version 강제하기  (0) 2024.02.15
    NodeJS - Event Loop  (0) 2021.12.10
    [NodeJS] 메일 전송 기능 구현 - Nodemailer + Gmail  (0) 2021.06.27
Designed by Tistory.