안녕세계

[Python] 암호화 라이브러리 (pycryptodome, pycryptodomex) 본문

[Python] 암호화 라이브러리 (pycryptodome, pycryptodomex)

Junhong Kim 2019. 1. 23. 23:29
728x90
반응형


사용자로부터 입력받은 데이터를 파이썬에서 암호화하는 방법에 대해 알아봅니다.

pycrypto 라이브러리를 fork하여 개선한 pycryptodome 또는 pycryptodomex를 사용하는 것을 권장합니다.


pycryptodome

- pycrypto를 대체하기 위해 개선된 라이브러리로 기존 코드와 호환됩니다.

$ pip install pycryptodome


pycryptodomex

- pycrypto와 독립적인 완전히 새로운 라이브러리입니다.

$ pip install pycryptodomex


Sample Code

import base64
import hashlib

from Cryptodome import Random
from Cryptodome.Cipher import AES
from django.conf import settings


class AESCipher:
    def __init__(self):
        self.BS = 16
        self.pad = lambda s: s + (self.BS - len(s) % self.BS) * chr(self.BS - len(s) % self.BS)
        self.unpad = lambda s: s[0:-s[-1]]
        self.key = hashlib.sha256(settings.SECRET_KEY.encode('utf-8')).digest()

    def encrypt(self, raw):
        raw = self.pad(raw).encode('utf-8')
        iv = Random.new().read(AES.block_size)
        cipher = AES.new(self.key, AES.MODE_CBC, iv)
        return base64.b64encode(iv + cipher.encrypt(raw))

    def decrypt(self, enc):
        enc = base64.b64decode(enc)
        iv = enc[:16]
        cipher = AES.new(self.key, AES.MODE_CBC, iv)
        return self.unpad(cipher.decrypt(enc[16:]))

    def encrypt_str(self, raw):
        return self.encrypt(raw).decode('utf-8')

    def decrypt_str(self, enc):
        if type(enc) == str:
            enc = str.encode(enc)
        return self.decrypt(enc).decode('utf-8')


Using Example

# 데이터 암호화
encrypted_data = AESCipher().encrypt_str(data)

# 데이터 복호화
decrypted_data = AESCipher().decrypt_str(data)


* Note

pycryptodomex를 사용하면 encoding 에러가 발생하기 때문에 다음과 같이 변경합니다.

def encrypt(self, raw):
    # raw = self.pad(raw)
    raw = self.pad(raw).encode("utf-8")
    iv = Random.new().read(AES.block_size)
    cipher = AES.new(self.key, AES.MODE_CBC, iv)
    return base64.b64encode(iv + cipher.encrypt(raw)

References


728x90
반응형
Comments