파이썬 웹 서비스 만들기

9. 데이터를 안전하게 주고 받기 - 9.1. 파이썬 itsdangerous 패키지

영바이트 2020. 11. 28. 11:41

 

이어지는 큰 주제로 비밀번호 재설정 기능을 다룰 것이다. 이 비밀번호 재설정 기능은 다양한 요소들로 구성되기 때문에 그 구성 요소들을 먼저 살펴보는 것이 기능의 구조와 동작 이해에 도움이 된다. 가장 먼저 암호화(encryption)와 복호화(decryption)에 대해 살펴보자.

 

비밀번호 재설정을 위해 비밀 번호를 바꾸려는 사용자가 누구인지, 이 사용자에게 제공하는 비밀번호 재설정 페이지의 주소는 어떻게 되는지 인터넷이라는 공개된 환경 아래서 데이터를 주고 받을 필요가 있다. 이들 정보들은 사용자와 관련된 아주 중요한 정보들이기 때문에 평문(plain text)으로 주고 받는 것은 보안 위험이 따른다. 따라서 중요한 정보들은 암호화와 복호화를 통해 주고 받는 것이 필수적이다.

 

암호화(Encryption)

 

암호화는 평문 메시지를 약속된 방법을 통해 암호문으로 만드는 과정이다. 암호문을 만들기 위해서 키(key)라고 하는 추가적인 데이터가 사용된다. 컴퓨터는 다양한 방법으로 평문과 키 데이터를 결합해서 암호문을 만든다.

 

 

복호화(Decpytion)

 

복호화는 암호문을 평문으로 바꾸는 과정이다. 복호화 과정에서 역시 키(key)가 필요하다. 컴퓨터는 키를 이용해서 암호문에서 원래 메시지 평문을 꺼낼 수 있다.

 

키(key)만 안전하게 주고 받을 수 있다면 메시지를 안전하게 주고 받을 수 있다. 키의 안전성을 높이기 위한 방법으로 비대칭 키(Asymmetric key) 암호화와 같이 암호화/복호화에 서로 다른 키를 사용하기도 한다. 이런 비 대칭키 암호화/복호화 방법도 있다는 정도로 알아두면 좋다.

 

 


 

 

메시지를 암호화하기 위해 파이썬의 itsdangerous 패키지를 사용할 것이다. 이 itsdangerous 패키지를 사용하여 메시지를 암호화해서 보안 토큰(token: 의미를 가진 작은 단위의 데이터)을 생성한다. 보안 토큰은 키(secret key)가 없으면 원래 메시지로 복호화(decryption)하는 것이 거의 불가능하기 때문에 공개된 환경인 인터넷을 통해 주고 받아도 큰 보안 위험은 발생하지 않는다. 예제를 통해 그 과정을 살펴보자.

 

이번 예제는 파이썬 인터랙티브 환경인 IDLE에서 진행할것이다. 아래와 같이 파이썬 IDLE을 실행시키자. 블로그의 포스팅들을 읽어온 독자라면 파이참 개발 환경과 파이썬 번역기가 이미 설치되어 있을 것이다. 만약 새로 설치가 필요하다면 개발환경 설정과 관련한 내용인 '파이썬 웹 프로그래밍 기본 - 2. 프로그래밍 환경 - 2.1. Pycharm' 포스팅을 참고하면 된다.

 

파이썬 IDLE 실행

 

IDLE 창이 뜨면 itsdangerous 패키지(모듈)의 TimedJSONWebSignatureSerializer 클래스를 가져오자.

from itsdangerous import TimedJSONWebSignatureSerializer as Serializer

 

만약 아래 그림과 같이 itsdangerous 패키지를 찾을 수 없다는 메시지가 나타나면 윈도우 커맨드 프롬프트를 관리자 권한으로 실행시키고 itsdangerous 패키지를 설치한다.

 

itsdangerous 파이썬 패키지를 찾을 수 없다는 메시지

 

윈도우 명령 프롬프트 실행(관리자 권한)

 

> pip3 install itsdangerous

 

itsdangerous 파이썬 패키지 설치

 

itsdangerous 파이썬 패키지 설치가 완료되었으면 secrets 패키지도 가져온다. secrets 패키지는 암호화에 필요한 키(key)를 생성하는데 사용된다.

from itsdangerous import TimedJSONWebSignatureSerializer as Serializer
import secrets

 

아래 명령들을 차례로 실행해서 키를 생성하고 확인해보자.

secretKey = secrets.token_hex(16)
secretKey

 

키 생성 결과

 

16바이트(16진수 32자리) 크기의 키 secretKey가 생성되었음을 확인할 수 있다.

 

생성한 비밀 키(secretKey)를 이용해서 다시 아래 명령어를 통해 30초 동안 유효한 암호화/복호화 객체를 생성하자.

s = Serializer(secretKey, 30)

 

이 객체를 이용해서 암호화/복호화를 할 수 있다. 사용자 ID를 저장한 {'user_id': 1} 파이썬 딕셔너리를 한 번 암화화 해보자.

token = s.dumps({'user_id': 1}).decode('utf-8')

 

암호화된 메시지인 암호 토큰의 내용을 확인해보면 임의의 문자열과 같이 실제 내용인 {'user_id': 1}과는 다른 내용이 나타난다.

 

암호 토큰 생성과 그 내용

 

 

생성된 암호 토큰은 아래 명령어를 이용해 원래 메시지로 복호화할 수 있다.

s.loads(token)

 

앞서 암호화/복호화 객체를 생성할 때 이 객체가 30초동안 유효하도록 설정하였다. 객체가 생성되고 30초 이전에는 정상적으로 암호화/복호화를 할 수 있지만 설정한 시간 이후에 암호 토큰을 복호화하려 하면 아래와 같이 SignatureExpired오류가 발생한다.

 

암호 토큰의 복호화

 

위에서 살펴본 암호화를 이용해 인터넷과 같은 개방된 환경 아래에서도 비교적 안전하게 메시지를 주고 받을 수 있다. 예를 들어 계정 정보, 계정 정보 수정 페이지 등을 암호토큰을 이용해서 계정 사용자와 주고 받으면 비밀번호와 같은 계정 정보를 웹 상에서 수정할 수 있다.

 

이어지는 포스팅들에서 암호 토큰을 이용해서 비밀번호화 같은 계정정보를 어떻게 수정할 수 있는지 계속 살펴보도록하겠다.