암호화 관련 전문 분야가 아니기 때문에 본인도 AES 정의는 검색에 의한 정리
AES
고급 암호화 표준 이라는 의미
암호화 및 복호화 동일한 키를 사용하는 대칭키 알고리즘
AES-128, AES-192, AES-256 으로 나눠지는데 Secret Key 의 길이에 따라 나눠짐
AES 를 사용해서 암호화 / 복호화 할 기회가 있어서 하게 되었고
어떤 데이터를 URL 에 노출 시켜야 되는 상황이 있어서 AES 암호화를 사용해서 암호화 했다.
그 때, 조금 찾아 보면서 고민했던 기억이 있어서 정리
AES 에 대해 잘 모르니까 본인도 검색을 하면서 만들어져 있는 소스도 가져다 써보고
했었는데 AES 마지막에 거의 대부분 base64(64진법) 인코딩을 사용 하는 것 같더라.
base64로 인코딩을 하는데 이게 URL 안에서 사용하기에는 불편함이 있다.
복호화 할 때, URL 을 파싱하는데 = / + 이런 text 들이 있어서 불편해서..
꼭 base64 로 인코딩을 해야되나??
하고 찾아봤었는데 hex(16진법) 로 해도 되는것 같다.
AES 암호화사이트 가 있는데 밑에 보면 선택하는 곳도 있고
Output Text Format: Base64 Hex
다른곳도 찾아보면 종종 hex 로 구현했다는 말이 있다.
( 64진법이 좀 더 안전은 하겠지??? 근데 뭐.. base64는 암호화 수준은 아니니까..)
일단 AES Key
암호화를 하는데 사용되는 Key는 16, 24, 32 byte 로 만 해야된다.
아니면 계속 이런식으로 오류난다.
ValueError: Incorrect AES key length (15 bytes)
( AES-128, AES-192, AES-256 -> Key 16, 24, 32 byte 순이다 )
여러 AES 만들어 놓은 걸 참고 하면서 본인은 AES-256, hex 를 이용해서 구현했다.
환 경
Python 3.10.1
pycryptodome==3.14.0
pip install pycryptodome==3.14.0
from Crypto.Cipher import AES
from Crypto import Random
# AES supports multiple key sizes: 16 (AES128), 24 (AES192), or 32 (AES256).
class AESCipher:
def __init__(self):
self.key = 'secret_key'
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[:-ord(s[len(s) - 1:])]
def encrypt(self, raw):
raw = self.pad(raw).encode()
iv = Random.new().read(AES.block_size)
cipher = AES.new(self.key.encode(), AES.MODE_CBC, iv)
return (iv + cipher.encrypt(raw)).hex()
def decrypt(self, enc):
enc = bytes.fromhex(enc)
iv = enc[:16]
cipher = AES.new(self.key.encode(), AES.MODE_CBC, iv)
return self.unpad(cipher.decrypt(enc[16:]).decode())
'Language > Python' 카테고리의 다른 글
[Python] type annotation (type hint) (0) | 2022.02.27 |
---|---|
[Python] pip requirements.txt (0) | 2022.01.31 |
[Python] Object type <class 'str'> cannot be passed to C code (AES) (0) | 2022.01.31 |
[Python] module 'time' has no attribute 'clock' (pycrypto) (0) | 2022.01.31 |
[Python] 환경 설정 (Vscode, Mac) (1) | 2022.01.09 |