프롤로그
아 좀 빡센데
3DES
DES(Data Encryption Standard 는 1970년대 IBM에서 파이스텔 블록구조에 기반하여 설계뙤고 개발된 56비트 암호화 알고리즘으로써 되게 인기있었지만 56비트라는 작은 암호키로 인하여 빠르게 깨졌다.현재 컴퓨팅 기술로 DES는 보안성이 결여되어 현재 사용하지 않는 암호화 알고리즘이 되어버렸다.
이를 보완하기 위하여 나온 게 3DES(Triple DES)인데, 3DES는 암호화를 위해 블록당 3번의 DES를 수행함. 즉 56 * 3 = 168비트 키 암호화 알고리즘이며, DES의 핵심 알고리즘의 변경없이 적용되었다. DES에 비해 보안적인 요소는 증가했지만 성능은 감소하였다.
CBC 모드라는 운영모드가 있는데, 이전 블록의 암호회된 블록과 XOR연산을 한 결과가 새로운 암호키로 해서 블록을 암호화 시키는 방법인데, 초기값은 우리가 직접 정해져야 한다. 그래서 초기화 벡터가 필요하다.
코드
from Crypto.Cipher import DES3
from Crypto.Hash import SHA256 as SHA
class myDES():
def __init__(self, keytext, ivtext):
hash = SHA.new()
hash.update(keytext.encode('utf-8'))
key = hash.digest()
self.key = key[:24]
hash.update(ivtext.encode('utf-8'))
iv = hash.digest()
self.iv = iv[:8]
def enc(self, plaintext):
des3 = DES3.new(self.key, DES3.MODE_CBC, self.iv)
encmsg = des3.encrypt(plaintext.encode())
return encmsg
def dec(self, ciphertext):
des3 = DES3.new(self.key, DES3.MODE_CBC, self.iv)
decmsg = des3.decrypt(ciphertext)
return decmsg
def main():
keytext = "samsjang"
ivtext = "12345678" # IV를 8바이트로 변경
msg = 'python3x'
myCipher = myDES(keytext, ivtext)
ciphered = myCipher.enc(msg)
deciphered = myCipher.dec(ciphered)
print("Original : \t%s" % msg)
print("Ciphered : \t%s" % ciphered)
print("Deciphered : \t%s" % deciphered)
main()
코드 분석
from Crypto.Cipher import DES3
from Crypto.Hash import SHA256 as SHA
3DES 라이브러리 사용을 위해 Pycrytodome 의 필요한 모듈 import한다.
DES3 만 쓸 거긴 한데, SHA256을 불러온 이유는 3DES의 암호킹하 초기화 벡터를 만들기 위해 쓴다.
class myDES():
def __init__(self, keytext, ivtext):
hash = SHA.new()
hash.update(keytext.encode('utf-8'))
key = hash.digest()
self.key = key[:24]
hash.update(ivtext.encode('utf-8'))
iv = hash.digest()
self.iv = iv[:8]
일단 이 부분은 keytext는 암호키 생성을 위한 문자열이며, ivtext는 초기화 벡터를 위한 문자열이다. keytext의 길이가 어떠하든 3DES가 지원하는 길이로 만들어서 이를 3DES의 키로 활용하면 보다 편하여서, SHA256 해쉬가 이런 작업을 해준다.
update쓰는 것은 모든 문자열은 유니코드 문자열을 인자로 받지 않기 위해서이다.
hash.digest() 로 해시값을 추출하여 변수 key에 저장한다. SHA256은 256비트 해시를 생성하므로 key는 32바이트 크기이다. 근데 3DES는 16또는 24바이트 크기이므로, key[:24]로 크기를 맞춰준다.
def enc(self, plaintext):
des3 = DES3.new(self.key, DES3.MODE_CBC, self.iv)
encmsg = des3.encrypt(plaintext.encode())
return encmsg
이 부분은 plaintext 에 담긴 문자열을 3DES로 암호화 하는 부분이다.
DES3.new(암호키, 운영모드, 초기화 벡터) 로 넣어준다.
def dec(self, ciphertext):
des3 = DES3.new(self.key, DES3.MODE_CBC, self.iv)
decmsg = des3.decrypt(ciphertext)
return decmsg
복호화도 마찬가지이다.
def main():
keytext = "samsjang"
ivtext = "12345678" # IV를 8바이트로 변경
msg = 'python3x'
myCipher = myDES(keytext, ivtext)
ciphered = myCipher.enc(msg)
deciphered = myCipher.dec(ciphered)
print("Original : \t%s" % msg)
print("Ciphered : \t%s" % ciphered)
print("Deciphered : \t%s" % deciphered)
main()
여기서 이제 keytext samsjang 을 넣고 ivtext 1234를 넣는다. keytext는 암호키 생성을 위한 거, 초기화 벡터를 위한 ivtext는 1234인 것이다. 우리가 기억하는 암호키는 samsjang이고, 코드 내부에서 실제 운영되는 암호키는 samsjang 의 SHA256 해시값중 처음 24바이트이다. ivtext도 마찬가지이다.
단 msg의 길이는 8바이트의 배우여야 하므로, 코드 하,나만 살짝 추가하자.
def make8String(msg):
msglen = len(msg)
filler = ''
if msglen%8 !=0:
filler = '0'*(8-msglen%8)
msg +=filler
return msg
8바이트의 배수로 만드는 과정이다.
def enc(self, plaintext):
plaintext = make8String(plaintext)
des3 = DES3.new(self.key, DES3.MODE_CBC, self.iv)
encmsg = des3.encrypt(plaintext.encode())
return encmsg
인코딩 부분 수정하면 된다.
결과적으로
Original : seominjae
Ciphered : b'\n\x17\x1eg6P\x18\xfe5k\xe9R\xa9\x86\xb0\xa1'
Deciphered : b'seominjae0000000'
PS D:\github\cryp>
이렇게 된다.
정리
myDES 클래스 :
DES3 알고리즘을 사용하여 텍스트를 암호화 및 복호화 하는데 사용
make8String 함수 :
주어진 문자열을 8의 배수 길이로 만들기 위해 0으로 채워진 문자열을 추가. DES3는 블록 단위로 작동하므로 메시지의 길이가 8의 배수여야함.
main 함수:
프로그램의 진입점. keytext와 ivtext 암호화에 사용할 키와 초기화 벡터를 정의
msg 는 암호화할 평문 정의
에필로그
아 이게 참 어렵네;;; 저 모듈의 함수를 이해해야하는데 좀 어렵습니다...
+ 글을 개판으로 쓴 거 인정합니다.
좀 정리한 것을
2024.01.18 - [스펙업/2024 winter-study] - [MATLAB] 매트랩에서 파이썬 코드 실행하기 (3DES)
여기에 재 정리 하였습니다.
'보안 스터디 > 암호학' 카테고리의 다른 글
[암호학] 암호화 해킹 #7 (스트림 암호와 ARC4) (0) | 2024.01.18 |
---|---|
[암호학] 암호화 해킹 #6 (AES 및 구현) (0) | 2024.01.18 |
[암호학] 암호화 해킹 #4 (대칭키 암호, Symmetric-key Cryptography) (0) | 2024.01.17 |
[암호학] 암호화 해킹 #3 (전치 암호 도구 만들기) (5) | 2024.01.14 |
[암호학] 암호화 해킹 #2 (카이사르 암호 도구 만들기) (2) | 2024.01.13 |