bcrypt, jwt / 양방향 암호화, 단방향 암호화

hukim·2020년 10월 15일
0
post-custom-banner

양방향 암호화

이미지 출처 : https://auth0.com/blog/hashing-passwords-one-way-road-to-security/

양방향 암호화는 비밀번호를 암호화하고 다시 복호화 할 수 있는 알고리즘입니다.

예를 들면, 특정 사이트에서 회원가입을 할 때 비밀번호를 입력하면 암호화해서 저장해 두었다가 다시 비밀번호를 찾을 때는 복호화해서 처음 입력한 비밀번호를 다시 찾을 수 있는 방식입니다.

대칭키(비공개키)와 비대칭키(공개키) 방식이 존재 하지만 각각 장단점이 존재합니다.

  • 대칭키 (비공개키)

    • 장점 : 속도가 빠르다.
    • 단점 : 키 배송 위험성이 존재하여 송신 측에서 수신 측에 암호 키를 전달하는 과정에서 노출우려 존재
  • 비대칭키 (공개키)

    • 장점 : 키 배송의 문제를 근본적으로 차단하여 안전성이 높다.
    • 단점 : 대칭키 방식에 비해서 느리다.

단방향 암호화

이미지 출처 : https://auth0.com/blog/hashing-passwords-one-way-road-to-security/

단방향 암호화는 평문을 암호화하는 것은 가능하지만 암호화된 비밀번호를 다시 평문으로 복호화하는 것이 어렵습니다. 그렇기 때문에 비밀번호를 관리할 때 유용하게 사용됩니다.

비밀번호가 한 번 암호화되면 복호화가 되지 않기 때문에 해당 개발자라 할지라도 다시 비밀번호를 알아내기가 힘듭니다. 유저가 입력한 비밀번호와 일치하는지만 확인이 가능합니다.

그래서 특정 사이트에서 비밀번호를 분실했을 때 비밀번호 찾기를 하면 기존 비밀번호를 알려주지 않고 새로운 비밀번호를 설정하라는 것이 단방향 암호화를 사용했기 때문입니다.

해시 함수를 이용한 단방향 암호화도 해킹이 절대 불가능하지는 않습니다.
그래서 좀 더 보완을 강력하게 하기 위해 salting , key stretching을 이용합니다.

salting

  • 임의의 문자열을 추가해서 암호화
  • 실제 비밀번호에 랜덤 값을 더해서 해시 값을 계산합니다.

key stretching

  • 해쉬 값을 여러번 반복해서 해시 하는 행위입니다.
  • 여러 번 반복하면 그만큼 해킹하는데 걸리는 시간이 길어집니다.

이러한 단방향 암호화를 사용하게 해주는 파이썬 라이브러리가 바로 bcrypt입니다.

bcrypt

pip install bcrypt

먼저 bcrypt 패키지를 설치해줍니다.

그리고 파이썬 shell을 이용해서 bcrypt로 암호화를 테스트 해봅니다.

bcrypt는 str 데이터가 아닌 Bytes 데이터를 암호화합니다. 그래서 암호화시에는 bytes로 인코딩을 해야합니다.

파이썬에서는 str을 encode하면 bytes(이진화)되고, Bytes를 decode하면 str화 합니다.
위의 이미지에서는 UTF-8 유니코드 문자 규격을 사용합니다.
암호화된 hased_password의 맨 앞부분에 보면 b라고 붙어있는데 이 부분은 Bytes 타입이라는 뜻입니다.

그렇다면, 이제 유저가 로그인을 시도했을 때 어떻게 비밀번호를 확인하는지 테스트해봅니다.

bcrypt의 checkpw() 메소드를 이용하면 해당 비밀번호가 암호화된 비밀번호와 일치하는지 혹은 일치하지않는지 판단할 수 있습니다.

비밀번호 둘 다 타입은 Bytes여야 합니다.

JWT (JSON Web Token)

이제는 인증을 위한 수단인 JWT (JSON Web Token)을 이용해서 토큰을 반환해보겠습니다.

pip install pyjwt

먼저 pyjwt 패키지를 설치합니다.

유저가 id, password를 입력해서 로그인 버튼을 누르면 서버는 id와 password를 db에 있는 것과 비교해서 인증이 완료되면 해당 유저에게 토큰을 발행해줍니다.

이러한 토큰은 사용자의 브라우저의 쿠키나 세션스토리지에 저장되어 서버에 데이터를 요청할 때 마다 토큰을 담아서 정보를 요청하고, 서버는 해당 토큰을 검증한 뒤 데이터를 전송합니다.

SECRET은 랜덤한 조합의 키 이지만 테스트이므로 단순하게 'secret'으로 작성했습니다.

이렇게 만들어진 토큰을 전달하면 됩니다.

이제 인증을 통과한 사용자만 접근하려면 토큰을 받아서 우리가 발행한 토큰이 맞는지 확인해야합니다.

decode 한 결과는 위에서 encode할 때 넘겼던 header 값인 {'id' : 1}입니다.

위에서 담아 넘기는 header 값을 통해서 유저를 식별할 수 있다는 뜻 입니다.

post-custom-banner

0개의 댓글