대칭키 암호(Symmetric-key CryptoGraphy)
지금까지 문자열들을 암호화 하였으니 이제 파일을 암호화하자!
내가 암호화 공부한 이유가 이런거 아닌가? 랜섬웨어 보면서 암호화에 대한 이론이 없으면 쓰나! 자자 정리해보자
우선, 3DES를 사용해 파일을 암호화 하는 코드를 작성해 보자.
3DES 파일암호화 코드
from Crypto.Cipher import DES3
from Crypto.Hash import SHA256 as SHA
from os import path
KSIZE = 1024
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 makeEncInfo(self, filename): # file의 크기를 구하고 8바이트 배수가 아닐 경우 0을 추가해 8바이트 맞쳐줌 / 0의 개수에 대한 정보를 헤더로 만들어 문자열로 리턴해줌
fillersize = 0
filesize = path.getsize(filename)
if filesize%8 != 0:
fillersize = 8 - filesize%8
filler = '0'*fillersize
header = '%d' %(fillersize)
gap = 8-len(header)
header += '#'*gap
return header, filler
# 1KB씩 읽어서 3DES로 암호화한 후 새로운 파일로 저장
def enc(self, filename):
encfilename = filename + '.enc' # .enc를 추가해서 파일을 만듬
header, filler = self.makeEncInfo(filename)
des3 = DES3.new(self.key, DES3.MODE_CBC, self.iv)
h = open(filename, 'rb') # 암호화를 위해 읽을 파일과 암호화 작업을 진행해 저장하기 위한 파일 두개를 open 한다.
hh = open(encfilename, 'wb+')
# 파일을 1KB 읽어 content에 저장
enc = header.encode('utf-8')
content = h.read(KSIZE)
content = enc + content
# 내용이 없을 때 까지 while문을 사용해 읽음
while content:
if len(content) < KSIZE:
content += filler.encode('utf-8')
enc = des3.encrypt(content)
hh.write(enc)
content = h.read(KSIZE)
h.close()
hh.close()
#1KB 읽어서 3DES로 복호화한 후 새로운 파일에 저장
def dec(self, encfilename):
filename = encfilename + '.dec'
des3 = DES3.new(self.key, DES3.MODE_CBC, self.iv)
#복호화 된 내용을 저장할 파일과 암호화된 파일을 오픈함
h = open(filename, 'wb+')
hh = open(encfilename, 'rb')
#암호화 파일을 8바이트 읽고 최초 8바이트 헤더는 # 구분자를 이용해 분리한 후 추가된 문자의 '0'의 개수를 얻는다.
content = hh.read(8)
dec = des3.decrypt(content)
header = dec.decode()
fillersize = int(header.split('#')[0])
content = hh.read(KSIZE)
while content:
dec = des3.decrypt(content)
if len(dec) < KSIZE:
if fillersize != 0:
dec = dec[:-fillersize]
h.write(dec)
content = hh.read(KSIZE)
h.close()
hh.close()
def main():
keytext = 'qingfro9'
ivtext = '1234'
filename = 'plain.txt'
encfilename = filename + '.enc'
myChipher = myDES(keytext, ivtext)
myChipher.enc(filename)
myChipher.dec(encfilename)
if __name__ == '__main__':
main()
AES 파일 암호화 코드
from Crypto.Cipher import AES
from Crypto.Hash import SHA256 as SHA
from os import path
KSIZE = 1024
class myAES():
def __init__(self, keytext, ivtext):
hash = SHA.new()
hash.update(keytext.encode('utf-8'))
key = hash.digest()
self.key = key[:16]
hash.update(ivtext.encode('utf-8'))
iv = hash.digest()
self.iv = iv[:16]
def makeEncInfo(self, filename):
fillersize = 0
filesize = path.getsize(filename)
if filesize%16 != 0:
fillersize = 16 - filesize%16
filler = '0'*fillersize
header = '%d' %(fillersize)
gap = 16-len(header)
header += '#'*gap
return header, filler
def enc(self, filename):
encfilename = filename + '.enc'
header, filler = self.makeEncInfo(filename)
aes = AES.new(self.key, AES.MODE_CBC, self.iv)
h = open(filename, 'rb')
hh = open(encfilename, 'wb+')
enc = header.encode('utf-8')
content = h.read(KSIZE)
content = enc + content
while content:
if len(content) < KSIZE:
content += filler.encode('utf-8')
enc = aes.encrypt(content)
hh.write(enc)
content = h.read(KSIZE)
h.close()
hh.close()
def dec(self, encfilename):
filename = encfilename + '.dec'
aes = AES.new(self.key, AES.MODE_CBC, self.iv)
h = open(filename, 'wb+')
hh = open(encfilename, 'rb')
content = hh.read(16)
dec = aes.decrypt(content)
header = dec.decode()
fillersize = int(header.split('#')[0])
content = hh.read(KSIZE)
while content:
dec = aes.decrypt(content)
if len(dec) < KSIZE:
if fillersize != 0:
dec = dec[:-fillersize]
h.write(dec)
content = hh.read(KSIZE)
h.close()
hh.close()
def main():
keytext = 'qingfro9'
ivtext = '1234'
filename = 'plain.txt'
encfilename = filename + '.enc'
myChipher = myAES(keytext, ivtext)
myChipher.enc(filename)
myChipher.dec(encfilename)
if __name__ == '__main__':
main()
무결설 검증을 위한 코드
두개의 파일을 구분하고 같은 파일임을 확인하는 코드 (SHA256 사용)
from Crypto.Hash import SHA256 as SHA
SIZE = 1024 * 256
def getFileHash(filename):
hash = SHA.new()
h = open(filename, 'rb')
content = h.read(SIZE)
while content:
hash.update(content)
hashval = hash.digest()
content = h.read(SIZE)
h.close()
return hashval
def hashCheck(file1, file2):
hashval1 = getFileHash(file1)
hashval2 = getFileHash(file2)
if hashval1 == hashval2:
print('Two file are same')
else:
print('Two file are different')
def main():
file1 = 'plain.txt'
file2 = 'plain.txt.enc.dec'
hashCheck(file1, file2)
if __name__ == '__main__':
main()
댓글 없음:
댓글 쓰기