python으로 AES 암호화 복호화

hive와 여러 DB에 보면 AES 암호화 복호화 하는 함수가 있다. hive 데이터 암호화, 복호화 링크를 참조하면 된다.

이번엔 python으로 암호화와 복호화를 구현해 보자.

라이브러리

PyCrypto 공식 개발은 2012 년에 끝났고, PyCryto를 대신하여 Python 3에서는 PyCrytodome를 사용할 수 있다. OS별로 받아야할 라이브러리가 다르다.

  • Linux
$ pip3 install pycryptodome
  • Windows
$ pip3 install pycryptodomex

코드

키 설정

암호화, 복호화에 필요한 키와 블럭 사이즈를 먼저 설정해 준다. 여기서 블럭 사이즈는 암호화 후 텍스트의 길이(?) 정도라고 생각해주면 될 것이다.

키는 16자리 이상의 문자열이어야 한다.

password = "dkssudsksmsEnddldi".encode('utf8')
aes = AES.new(password, AES.MODE_ECB)
block_Size = 16

암호화

암호화 과정은 아래와 같다.

  1. 암호화할 text를 utf-8 인코딩(byte 형식으로 변환)
  2. byte 형식으로 변환된 text를 블록들로 변환해 준다.(padding)
  3. 암호화(encrypt -> base64 -> utf-8 디코딩)

코드는 아래와 같다.

def encrypt(text):
    byted_text = text.encode("utf8")
    # 암호화의 대상인 text를 16, 32, 64, 128, 256 바이트의 블록들로 변환해준다.
    padded_text = pad(byted_text, block_Size)
    encrypted_text = base64.b64encode(aes.encrypt(padded_text)).decode('utf-8')  # 암호화(encrypt -> base64 -> utf-8)
    return encrypted_text

복호화

복호화 과정은 암호화 과정의 반대로 하면 된다.

  1. 복호화(utf-8 인코딩 -> base64 -> decrypt)
  2. 블록형태인 byte 형식의 text를 unpadding 하고
  3. utf-8 디코딩 한다.

코드는 아래와 같다.

def decrypt(encrypted_text):
    decrypted_text = aes.decrypt(base64.b64decode(encrypted_text.encode('utf-8')))  # 복호화(utf-8 -> base64 -> decrypt)
    # 블록으로 만들었던 것을 원래의 상태대로 돌린다.
    unpadded_text = unpad(decrypted_text, block_Size)
    origin_text = unpadded_text.decode('utf-8')
    return origin_text

전체코드

전체 코드는 아래와 같다.

import base64

from Cryptodome.Cipher import AES
from Cryptodome.Util.Padding import pad, unpad


password = "dkssudsksmsEnddldi".encode('utf8')
# key = hashlib.pbkdf2_hmac(hash_name='sha256', password=password, salt=b'$3kj##agh_', iterations=100000)
aes = AES.new(password, AES.MODE_ECB)
block_Size = 16

def encrypt(text):
    byted_text = text.encode("utf8")
    # 암호화의 대상인 text를 16, 32, 64, 128, 256 바이트의 블록들로 변환해준다.
    padded_text = pad(byted_text, block_Size)
    encrypted_text = base64.b64encode(aes.encrypt(padded_text)).decode('utf-8')  # 암호화(encrypt -> base64 -> utf-8)
    return encrypted_text

def decrypt(encrypted_text):
    decrypted_text = aes.decrypt(base64.b64decode(encrypted_text.encode('utf-8')))  # 복호화(utf-8 -> base64 -> decrypt)
    # 블록으로 만들었던 것을 원래의 상태대로 돌린다.
    unpadded_text = unpad(decrypted_text, block_Size)
    origin_text = unpadded_text.decode('utf-8')
    return origin_text

def main():
    text = input("텍스트: ")

    encrypted_text = encrypt(text)
    print("암호화된 텍스트: ", encrypted_text)

    decrypted_text = decrypt(encrypted_text)
    print("복호화된 텍스트: ", decrypted_text)

if __name__ == "__main__":
    main()

Leave a comment