사용자 도구

사이트 도구


python:crypto

차이

문서의 선택한 두 판 사이의 차이를 보여줍니다.

차이 보기로 링크

양쪽 이전 판이전 판
다음 판
이전 판
python:crypto [2024/02/02 13:40] – [준비하기] taekgupython:crypto [2025/04/15 10:05] (현재) – 바깥 편집 127.0.0.1
줄 1: 줄 1:
 +====== 파이썬에서 암호화에 대하여 ======
 +  * [[python:django:bcrypt|bcrypt를 이용한 암호화 하기]]
  
 +===== PyCrypto =====
 +
 +PyCrypto(Python Cryptography Toolkit) 모듈은 2004년에 정식 버전이 배포된 오래된 암호화 모듈이다.
 +
 +하지만 pip에는 2013년 10월 18일에 마지막 버전인 pycrypto 2.6.1을 배포한 이후 더이상 업데이트되지 않고 있다.
 +
 +github에는 2014년 6월 20일에 마지막으로 커밋된 코드를 찾아볼 수 있다.
 +
 +게다가 block_templace.c의 ALGnew 함수에서 임의 코드 실행 공격이 가능한 힙 버퍼 오버플로우 취약점이 발견되어 CVE-2013-7459에 등록되었다.
 +
 +이 취약점에 대한 패치를 발표하지 않고 더이상의 업데이트도 찾아 볼 수 없다.
 +
 +그래서 PyCrypto를 계승한 PyCryptodome을 사용하길 권장한다.
 +
 +===== PyCryptodome =====
 +
 +PyCryptodome은 PyCrypto를 fork하여 제작된 거의 동일한(drop-in replacement) 모듈이다.
 +
 +즉 기존 프로그램에서 사용하던 PyCrypto를 정말 그대로 사용할 수 있도록 도와준다.
 +
 +그래서 파이썬 코드에서 import 할 때도 Crypto를 import 한다.
 +
 +===== PyCryptodomex =====
 +
 +PyCryptodome을 사용하다보면 PyCryptodomex라는 패키지도 찾아볼 수 있다.
 +
 +PyCryptodomex는 PyCryptodome의 standalone 버전이다.
 +
 +PyCrypto와 PyCryptodome을 동시에 사용할 때 발생할 수 있는 문제(이름 등) 등을 회피하기 위해 만들어진 패키지다.
 +
 +PyCryptodomex를 설치한 경우 Cryptodome을 import 해야 한다.
 +
 +
 +===== 준비하기 =====
 +파이썬에서 암호화 알고리즘 **DES(DES3)**나 **AES**, 해시함수 **MD4**,**MD5** **SHA**를 이용하기 위해서는 //Crypto// 모듈이 필요합니다.
 +**Crypto** 모듈은 기본으로 설치되어있는 모듈이 아니므로 모듈을 설치해야 합니다.
 +
 +=== pycryptodome ===
 +  pycrypto를 대체하기 위해 개선된 라이브러리로 기존 코드와 호환됩니다.
 +
 +=== pycryptodomex ===
 +  pycrypto와 독립적인 완전히 새로운 라이브러리입니다.
 +
 +1. crypto 모듈을 설치
 +<code bash>
 +pip install pycryptodomex
 +</code>
 +
 +2. python에서 Crypto 모듈을 import 합니다.
 +<code python>
 +import Crypto
 +</code>
 +
 +===== Sample Code =====
 +<code python maro_crypto.py>
 +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')
 +</code>
 +====== 참조 ======
 +참조) [[https://codedatasotrage.tistory.com/2]]