ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 암호화에 대한 이해
    IT 지식 2021. 3. 7. 16:34
    728x90

    저번 포스팅에서는 암호화가 무엇인지에 대한 소개 없이, 바로 암호화를 하는 방식에 대해 소개해드렸는데요. 오늘은 저번 시간에 이어서 암호화에 대한 이해와 그 방식에 대해 알아보는 시간을 가져보도록 하겠습니다. 

     

    1. 암호화란?

     

    암호화라는 말의 의미는 우리가 일상적으로 쓰는 평문을 다른 사람들이 쉽게 이해할 수 없도록 암호문으로 바꾸는 과정을 말합니다. 반대로 암호화된 문장을 이해할 수 있도록 암호문을 평문으로 바꾸는 과정을 복호화 라고 합니다.  키(Key)와 알고리즘을 통해 암호화와 복호화가 이루어지며, 이러한 일련의 과정들을 암호화 시스템이라고 합니다. 

     

    2. 암호화의 방식

     

    암호화의 방식에는 크게 대칭키 방식, 비대칭키 방식, 해쉬함수로 분류할 수 있습니다.

     

    1) 대칭키 방식

     

    대칭키 방식은 암호화 키와 복호화 키가 같은 것을 의미합니다. 따라서 암호화 하는 측과 복호화 하는 측이 같은 암호키를 공유해야 합니다. 다른 방식과 비교해서 계산 속도가 빠르다는 장점이 있지만, 키가 여러군데에서 공유되는 만큼 암호화 키를 관리하는 것이 복잡하고 어렵다는 단점이 존재합니다. 

     

    2) 비대칭키 방식

     

    비대칭키 방식은 암호화 키와 복호화 키가 다른 것을 의미합니다. 서로의 키가 다르다보니, 키를 양 측에서 공유할 필요가 없습니다. 또한 그만큼 키를 관리하기 수월하다는 장점이 있습니다. 하지만 대칭키 방식에 비해 계산 속도가 느리다는 단점이 존재합니다. 

     

    3) 해시 방식

     

    해시란 단방향 암호화 기법으로 해시함수를 이용하여 고정된 길이의 암호화된 문자열로 바꾸는 방식을 말합니다. 해시함수는 임의의 길이의 데이터를 고정된 길이의 데이터로 매핑하는 함수를 의미합니다. 이때 매핑 전 원래 데이터의 값을 키, 매핑 후 데이터의 값을 해시값, 매핑하는 과정을 해싱 이라고 합니다.

    해시 알고리즘은 모두에게 공개되어 있는만큼, 해커들도 그 알고리즘을 알고 있습니다. 그래서 보안이 뚫린 해시 함수가 존재하는데, MD-5, SHA-1, HAS-180이 보안이 뚫린 함수들이라고 할 수 있습니다. 최근에는 SHA-256, SHA-512등의 알고리즘을 사용하기를 권고하고 있습니다.

     

    3. crypto 모듈로 암호화 하기

     

    자바스크립트에는 crypto라는 모듈이 있습니다. 이 모듈을 활용하면 지난 시간처럼 라이브러리를 활용하지 않더라도 쉽게 암호화를 할 수 있습니다. 오늘 사례에서는 Node에서 crypto를 활용하는 코드를 예시로 보여드리도록 하겠습니다.

     

    const crypto = require('crypto');
    crypto.createHash('sha512').update('비밀번호').digest('base64'); // 'dvfV6nyLRRt3NxKSlTHOkkEGgqW2HRtfu19Ou/psUXvwlebbXCboxIPmDYOFRIpqav2eUTBFuHaZri5x+usy1g=='
    crypto.createHash('sha512').update('비밀번호').digest('base64'); // 위와 같은 결과
    crypto.createHash('sha512').update('비밀번호').digest('hex'); // '76f7d5ea7c8b451b773712929531ce92410682a5b61d1b5fbb5f4ebbfa6c517bf095e6db5c26e8c483e60d8385448a6a6afd9e513045b87699ae2e71faeb32d6'
    
    //출처: https://www.zerocho.com/category/NodeJS/post/593a487c2ed1da0018cff95d

     

    암호화의 예시는 제로초님의 블로그에서 가져왔습니다. node에서는 crypto 모듈을 활용하기 위해 require를 통해 모듈을 가져와야 합니다. 그 후 crypto 모듈에 내장되어 있는 함수를 통해 데이터를 해싱 할 수 있습니다.

     

    하지만 이 방식은 내가 입력한 데이터에 따라 항상 같은 결과물이 나오기 때문에, 만약 해커가 가능한 경우의 수에 대해 데이터베이스화 해두었다면 쉽게 뚫릴 수 있습니다. 따라서 해커가 데이터베이스를 활용하지 못하도록 소금을 뿌려주는 것이 필요합니다. salt라는 특정 값을 통해서 해시의 결과값을 바꿔줄 수 있습니다. 

     

    crypto.randomBytes(64, (err, buf) => {
      crypto.pbkdf2('비밀번호', buf.toString('base64'), 100000, 64, 'sha512', (err, key) => {
        console.log(key.toString('base64')); // 'dWhPkH6c4X1Y71A/DrAHhML3DyKQdEkUOIaSmYCI7xZkD5bLZhPF0dOSs2YZA/Y4B8XNfWd3DHIqR5234RtHzw=='
      });
    });
    
    //출처: https://www.zerocho.com/category/NodeJS/post/593a487c2ed1da0018cff95d

     

    위의 함수를 보시면 randomBytes 메소드로 64바이트 길이의 salt를 생성하고 있습니다. 위의 buf는 버퍼 형식이기 때문에, buf.toString('base64')로 base64 문자열 salt로 변경해줍니다. pbkdf2는 단방향 암호화시 가장 많이 사용되는 방식 중 하나입니다.

     

    pbkdf2에는 인자가 5개 필요합니다. 비밀번호, salt, 반복 횟수, 비밀번호 길이, 해시 알고리즘 순서 입니다. 역시나 이번에도 key는 버퍼 형식으로 나오기 때문에, toString메소드를 사용해주어야 합니다. 반복횟수는 위의 예시에서 10만번으로 설정되어 있는데, 이 정도 반복은 요즘 컴퓨터 기준으로 1초가 채 안걸립니다. 숫자가 높을 수록 해커들이 데이터베이스화 하기 힘들어집니다. 또한 반복 횟수도 딱 떨어지는 수 보다는 불규칙적인 숫자를 활용하는 것이 좋습니다. 

     

    salt와 key를 같이 저장해야 한다는 것을 꼭 기억하셔야 합니다. 위의 randomBytes는 매번 다른 salt값을 리턴하기 때문에 암호화 결과가 매번 달라집니다. 같은 salt를 사용해야 비교가 가능해집니다. 

     

    crypto.pbkdf2('입력비밀번호', '기존salt', 100000, 64, 'sha512', (err, key) => {
      console.log(key.toString('base64') === '기존 비밀번호');
    });
    
    //출처: https://www.zerocho.com/category/NodeJS/post/593a487c2ed1da0018cff95d

     

    4. 마치며

     

    오늘은 자바스크립트의 내장 모듈로 단방향 해시 암호화를 하는 방법에 대해 알아보았습니다. 아직은 이 방식을 실무에 어떻게 적용시켜야할지 감이 잘 안오는데요, 다양한 토이프로젝트나 테스트 등을 통해서 이 해시 암호화를 익혀야 할 것 같습니다.

    728x90

    댓글

Designed by Tistory.