본문 바로가기
모의해킹 침해대응 과정/본 과정

암호학 / 블록 암호 모드 구현(by python)

by 알거음슴 2021. 6. 23.

python을 통한 블록암호구현

 

1. 3DES - CBC 를 통한 메시지 암,복호화 구현

평문 -> 3DES & CBC mode -> 암호문 프로그램 구현

from Crypto.Cipher import DES3 as DES
from Crypto.Hash import SHA256 as SHA


class MyDES:

    def __init__(self, key, iv):
        myhash = SHA.new()

        myhash.update(key.encode())
        tkey = myhash.digest()
        self.key = tkey[:24]

        myhash.update(iv.encode())
        tiv = myhash.digest()
        self.iv = tiv[:8]

    def enc(self, msg):
        msg, fillernum = self.make8string(msg)
        des3 = DES.new(self.key, DES.MODE_CBC, self.iv)
        encmsg = des3.encrypt(msg.encode())

        return encmsg, fillernum

    def dec(self, msg, fillernum):
        des3 = DES.new(self.key, DES.MODE_CBC, self.iv)
        decmsg = des3.decrypt(msg)
        decmsg = decmsg.decode()

        if fillernum != 0:
            decmsg = decmsg[:-fillernum]

        return decmsg

    def make8string(self, msg):
        msglen = len(msg)
        filler = ''
        if msglen % 8 != 0:
            filler = '0' * (8 - msglen % 8)

        fillernum = len(filler)
        msg += filler

        return msg, fillernum


def main():
    mymessage = 'We are no longer the knights who say ni!'
    keytext = 'samsjang'
    ivtext = '1234'

    mycipher = MyDES(keytext, ivtext)
    encrypted, fillter_num = mycipher.enc(mymessage)
    print("Plaintext :", mymessage)
    print("Encrypted :", encrypted)

    decrypted = mycipher.dec(encrypted, fillter_num)
    print("Decrypted :", decrypted)


# main execution
if __name__ == '__main__':
    main()

'''
Plaintext : We are no longer the knights who say ni!
Encrypted : b"\xd5\xb2\xf1\x01|wa\x00\xeeMoHb\xc3\xcc\x8dN\x83\x16\xd0{\xd3>9'\xc3\x00X\x1dk\xfa>\x83/\xb04\rc\x1b2"
Decrypted : We are no longer the knights who say ni!
'''

 

 

 

2. AES - CBC 를 통한 메시지를 암,복호화 구현

평문 -> AES & CBC mode -> 암호문 프로그램 구현

from Crypto.Cipher import AES
from Crypto.Hash import SHA256 as SHA


class MyAES():
    def __init__(self, keytext, ivtext):
        myhash = SHA.new()
        # key create
        myhash.update(keytext.encode('utf-8'))
        key = myhash.digest()
        self.key = key[:16]

        myhash.update(ivtext.encode('utf-8'))
        iv = myhash.digest()
        self.iv = iv[:16]

    def make_enabled(self, plaintext):
        textsize = len(plaintext)
        fillersize = 0
        if textsize % 16 != 0:
            fillersize = 16 - (textsize % 16)

        filler = '0' * fillersize
        header = '%d' % fillersize
        gap = 16 - len(header)
        header += '#' * gap

        return header + plaintext + filler

    def enc(self, plaintext):
        plaintext = self.make_enabled(plaintext)
        aes = AES.new(self.key, AES.MODE_CBC, self.iv)
        encmsg = aes.encrypt(plaintext.encode())

        return encmsg

    def dec(self, ciphertext):
        aes = AES.new(self.key, AES.MODE_CBC, self.iv)
        decmsg = aes.decrypt(ciphertext)

        header = decmsg[:16].decode()
        fillersize = int(header.split('#')[0])
        if fillersize != 0:
            decmsg = decmsg[16:-fillersize]
        else:
            decmsg = decmsg[16:]

        return decmsg


def main():
    message = 'We are no longer the knights who say ni!'
    # message = 'abcde'
    keytext = 'samsjang'
    ivtext = '1234'

    mycipher = MyAES(keytext, ivtext)
    ciphered = mycipher.enc(message)
    deciphered = mycipher.dec(ciphered)

    print('Original   :', message)
    print('Encrypted  :', ciphered)
    print('Decrypted  :', deciphered.decode())


if __name__ == '__main__':
    main()

'''
Original   : We are no longer the knights who say ni!
Encrypted  : b'v[\xac\xcar#\xf6q\x19\x0e\x0cr\x1d\x01\xf1\x1c\x0e\xc4\xedJ\xf4\x80M\xe7\xc0@\xa0\xa0i\x93R\xb9v\xb5\xc3\xba\xaa\xda\xba\x0e4\x0e\xb3\xb76(m\x9b\xa7\xf2G\x84O~$\xb7s\x9aU\x9c|\xae\xbbT'
Decrypted  : We are no longer the knights who say ni!
'''

 

 

3. AES - CTR 를 통한 메시지를 암,복호화 구현

평문 -> AES & CTR mode -> 암호문 프로그램 구현

from Crypto.Cipher import AES
from Crypto.Random import get_random_bytes

# Cipher Algorithm : AES
# * input : 128 bits block(16 bytes)
# * key   : 128(16), 256(32), 512(64) bits
# * output: 128 bits block(16 bytes)
# * IV (X)
# Cipher Mode : CTR
# * nonce   : 초기화시 설정되는 고정된 nonce(비표) -> 상대에게 보내줘야 하는 값
# * counter : 1씩 증가(빅엔디안 인코딩)

#
# (1) Encryption
#
message = b'hello world!'
key = get_random_bytes(16)

cipher1 = AES.new(key, AES.MODE_CTR)
ciphertext = cipher1.encrypt(message)
nonce = cipher1.nonce

print('Message    :', message.decode())
print('Ciphertext :', ciphertext)

#
# (2) Decryption
#
received_cipher = ciphertext
received_nonce = cipher1.nonce

cipher2 = AES.new(key, AES.MODE_CTR, nonce=received_nonce)
plaintext = cipher2.decrypt(received_cipher)
print('Plaintext   :', plaintext.decode())


'''
Message    : hello world!
Ciphertext : b'\xb1\x97\x1b\xee\xe3>\xb3ew#w\x97'
Plaintext   : hello world!
'''

 

 

4. AES - EAX 를 사용하여 메시지 암,복호화 구현

json 포멧을 통해 암호화하여 송신하고 수신측에서 복호화 진행한다.

###!/usr/bin/python3
#
# AES-CTR
# (1) AES Cipher
#   * input     : 16 bytes
#   * key       : 16 bytes
#   * output    : 16 bytes
# (2) CTR Cipher Mode
#   * nonce
# (3) Cipher Authentication and Verify
#   * tag

import json
from base64 import b64encode, b64decode
from Crypto.Cipher import AES
from Crypto.Random import get_random_bytes

def main():
    header = b'header'
    data = b'hello world!'
    key = get_random_bytes(16)
    print("Plaintext :", data)

    #encrypted
    cipher1 = AES.new(key, AES.MODE_EAX)
    cipher1.update(header)
    ciphertext, tag = cipher1.encrypt_and_digest(data)
    # print(ciphertext, tag)

    json_key = ['nonce', 'header', 'ciphertext', 'tag']
    json_value = [b64encode(x).decode() for x in (cipher1.nonce, header, ciphertext, tag)]
    # print(json_key, json_value)
    send_data = json.dumps(dict(zip(json_key, json_value)))
    print("Encrypted :", ciphertext)
    print("Send_mag :", send_data)

    #decrypted
    recv_data = send_data
    b64 = json.loads(recv_data)

    json_key = ['nonce', 'header', 'ciphertext', 'tag']
    json_value = ({k:b64decode(b64[k]) for k in json_key})

    cipher2 = AES.new(key, AES.MODE_EAX, nonce=json_value['nonce'])
    cipher2.update(json_value['header'])
    ciphertext2 = cipher2.decrypt_and_verify(ciphertext, tag)
    print("Decrypted :", ciphertext2)

if __name__ == '__main__':
    main()
    
 '''
 Plaintext : b'hello world!'
Encrypted : b'\x19\xf7\t\xdfQ4\xb5z\xa0}N\xd1'
Send_mag : {"nonce": "J0YimLaqLsA/VpfdcB0uqg==", "header": "aGVhZGVy", "ciphertext": "GfcJ31E0tXqgfU7R", "tag": "2Gr2+/tPIN9b3y1ppvbbsA=="}
Decrypted : b'hello world!'
 '''

 

5. 3DES_CBC 사용하여 파일에 암,복호화 저장하기

File1 -> plaintext -> E(msg) -> cipertext -> File2

###!/usr/bin/python3
#
# DES3-CBC
# 1) DES3 Cipher Algorithm
#   * input : 8 bytes
#   * key   : 8 bytes(8|16|24)
#   * output: 8 bytes
# 2) CBC Cipher Mode
#   * iv    : 8 bytes
#   * pad, unpad
from Crypto.Cipher import DES3
from Crypto.Random import get_random_bytes
from Crypto.Util.Padding import pad, unpad


class MyDES3_CBC:
    # argument:
    #
    # property:
    #   * self.iv:
    #   * self.key:
    # function:
    #   * enc()
    #       pfile -> Encryption -> cfile
    #   * dec()
    #       cfile -> Decryption -> pfile
    def __init__(self):
        self.key = get_random_bytes(24)
        self.iv = get_random_bytes(8)

    def enc(self, pfile):
        cfile = pfile + '.enc'

        fd1 = open(pfile, 'rb')
        fd2 = open(cfile, 'wb')
        plaintext = fd1.read()

        cipher1 = DES3.new(self.key, DES3.MODE_CBC, self.iv)
        ciphertext = cipher1.encrypt(pad(plaintext, 8))
        fd2.write(ciphertext)

        fd1.close()
        fd2.close()

        return cfile

    def dec(self, cfile):
        pfile = cfile + '.dec'

        fd1 = open(cfile, 'rb')
        ciphertext = fd1.read()

        cipher2 = DES3.new(self.key, DES3.MODE_CBC, self.iv)
        plaintext = unpad(cipher2.decrypt(ciphertext), 8)

        fd2 = open(pfile, 'wb')
        fd2.write(plaintext)
        fd2.close()

        return pfile


def main():
    myfile = 'plain.txt'

    print("Original File(%s) Content:" % myfile)
    print(open(myfile).read())
    print('')

    des3 = MyDES3_CBC()

    encfile = des3.enc(myfile)
    print("Encrypted File(%s) Content:" % encfile)
    print(open(encfile, 'rb').read())
    print('')

    decfile = des3.dec(encfile)
    print("Decrypted File(%s) Content:" % decfile)
    print(open(decfile).read())


if __name__ == '__main__':
    main()

'''
Original File(plain.txt) Content:
Robin Monroe (Anne Heche) is a New York City journalist who works for Dazzle, a fashion magazine. She is invited by her boyfriend Frank (David Schwimmer) to spend a week holidaying with him on the island paradise of Makatea, in the South Pacific. The final leg of their journey to Makatea is in a dilapidated de Havilland Canada DHC-2 Beaver, piloted by middle-aged American Quinn Harris (Harrison Ford). They are accompanied by Quinn's girlfriend and co-pilot Angelica (Jacqueline Obradors). On their first night on the island, Frank proposes to Robin, who happily accepts. At a bar, a drunken Quinn makes a move on Robin, which she rejects as Frank appears.

Encrypted File(plain.txt.enc) Content:
b"\x86\x8e\xb1\xcd4\xecP\x9f\xcd\xbdM\t5\xb7\xa7\xb5\xab\xe9\xd3j\xa0\n~\xb8us\x7fIY\tw\xa8|\x9d\x8e\xa4\xb3*\x0c\x83\xf0ig\x9c\xe3,P=K\xcf\x92\xb0\xaf\xf0\xc1\xa4\xcf\xd7\xf5\xcf\x05\xc9x\xc6v\xd8X\x9c\x8d\t\xa1z\x9d<F\x00'\xfa\xd6\x18\xd9i\xc5)\x81Q\x05|\x04\x1f\xc9a;\xfc\xfd\xf6N\xcb\x10\x9cA\xd9#'\xe2P\xa4\x9fw\xa2\xc6\xae\nZ~x</\x17\x89\xbaO\x8e\xdad\x08c\x08dS\xb6;\xb7Cv\x11,\x89\xf4N\xd2,\x94\xf3\xa3k^\xf0\x02\x94i\xcbie\x8a\x95E\xd9i\xd3\x9e\x02\x82\x1b\xa7X\xb3\xf6 \xff\x8a\xbaS\xf6V\x0f\x92\x15f\x0f\x99\x97j\x8fN\xb3\xd0\x0b?\xbb\x11>P\xb79\n\xaae}\xce9Kh\xb7\xb6\xc8\xa7&\xe3\xa2\xa2\xc4>\xb2\xcf}\xc5E&\x99brM\xba,\xf0gS\xd1\xd4\xee\xc3e=\xdaR\xd9\x80\x81\x0f\xcd\x00\x1f\x18\xa6\xc8\x01\x91P|rn\xf6\x86r)\xc4{\x806\x136\xe6\x92\x0c\x15+2\x99'\xaa#\xa9\t@\x19\xf5\x1e\xfdw\xd7*A\x07\xfa\xd3\xb6\x82\xd2z\xd0\xc4N\x99]\xb9\xf2\xdb\xc6\x87\xc8,\xcf[Q\xba\x04\xeffQi\xee\x80B\xfa\\'h\xbbI\xd9p\x82\x14\xf0\xc7:\x10G\xf0My2\x87\xd5\xec\x9a\xd4\xf0\xef\xfc:\x7fL@\xd1\x0f\x1dtg&V\xed\xc5\x19d\xdeBS\xd4?\x1d>\xc8\x08B\xb6\xfd\x8a%\x13\x1dm\x88\xcc\x93\xd4C\x93\xc75\xd6\x0c\x14\x85\xac\xb8B\x9e+\xeb\xe8\xcdgX\xe4\x87\xe7\xe3e\xcd\x0c\x07\xd8\x07\xb5\xd9\x1b]\x94\xdc\xe9\x0f\xb6\xf6\xd5\xed\x04>\x97PO\x90c\x91q\x03\x9c\xc7X\xa7Il[\xcbd\xfa\xad\xbcj>8\xd4\x01\x9f\x1fU~\x18\xf6\x05\x9e\xffm\xfe\x10\xbd`3\x04\xc3\x1d\xe5\x1f\x80\xa1y\n\xf5\x0b\xd7\x12\xda\x95H7\xb2r_~\xf4P\xc2\xabVW$\x91\xd4\xa1\x82\x19,\x82O\xa0\x1c\xfc\x82Cx\xfe\x97@\xff*\xbf8e\x1d\x18\xca\xee\xae9\xb6yt8\xf1\x88\t\xd4\xbaOY\xf2\xf2O\xab\x99\x9e\xe3;r\x96\x16\xde\x83\xbdl\xc5_r\r\xdc\x81\x00\xa7h\x19\xf3/L\xab\x03\xca\xa1\xb6\x8f\xd6\xd0\x91\x8a\xfe~K\xff\x84\xe3m\x164\x08;\x12y\xcf\xbf\x81\xe8}\xe8\x88J\x17e\x8a\x14\xb6\xd3>\x04|-\xe3\xfe\xc3t\xcfK\n\xd3\xe1\xeb\x81$\xaaP\x82jo\x81\x82\xf0\xe4P\x0c!n\xcdc\xad\xfcSH\x89Y.\xb3\xf6\x1a^\xd1\xe5VV\x1ba=\xac\x1cT\xd8I\xcfT\xda\x0f\x7f\xdf\xa6Q3p\xf7\xaf=\x07\xb3\xf6_C)"

Decrypted File(plain.txt.enc.dec) Content:
Robin Monroe (Anne Heche) is a New York City journalist who works for Dazzle, a fashion magazine. She is invited by her boyfriend Frank (David Schwimmer) to spend a week holidaying with him on the island paradise of Makatea, in the South Pacific. The final leg of their journey to Makatea is in a dilapidated de Havilland Canada DHC-2 Beaver, piloted by middle-aged American Quinn Harris (Harrison Ford). They are accompanied by Quinn's girlfriend and co-pilot Angelica (Jacqueline Obradors). On their first night on the island, Frank proposes to Robin, who happily accepts. At a bar, a drunken Quinn makes a move on Robin, which she rejects as Frank appears.

Process finished with exit code 0
'''

 

6. AES_CBC 사용하여 파일에 암,복호화 저장하기

File1 -> plaintext -> E(msg) -> cipertext -> File2

from Crypto.Util.Padding import pad, unpad
from Crypto.Cipher import AES
from Crypto.Random import get_random_bytes

# Cipher Algorithm : TDES
# * input : 64 bits block(8 bytes)
# * key   : 64 bits x 3 = 192 bits(24 bytes)
# * output: 64 bits block(8 bytes)
# * Padding
# Cipher Mode : CBC
# * IV


class MyAES_CBC:
    def __init__(self):
        self.key = get_random_bytes(16)
        self.iv = get_random_bytes(16)

    def enc(self, filename):
        # 저장할 파일이름
        encfilename = filename + '.enc'

        # 읽을 파일 fd1, 쓸 파일 fd2
        fd1 = open(filename, 'rb')
        fd2 = open(encfilename, 'wb+')
        filecontent = fd1.read()

        # AES 객체 생성
        # fd1 파일을 읽어서 암호화 한후 fd2 저장하기
        # 중간에 암호화시 패딩처리를 하였다.
        cipher = AES.new(self.key, AES.MODE_CBC, self.iv)
        ciphertext = cipher.encrypt(pad(filecontent, 16))
        fd2.write(ciphertext)

        # 파일 닫기
        fd1.close()
        fd2.close()

        return encfilename

    def dec(self, encfilename):
        decfilename = encfilename + '.dec'

        fd1 = open(encfilename, 'rb')
        fd2 = open(decfilename, 'w')
        content = fd1.read()

        aes = AES.new(self.key, AES.MODE_CBC, self.iv)
        plaintext = unpad(aes.decrypt(content), 16)
        fd2.write(plaintext.decode())

        fd1.close()
        fd2.close()

        return decfilename


def main():
    myfile = 'plain.txt'

    aes = MyAES_CBC()
    encfile = aes.enc(myfile)
    decfile = aes.dec(encfile)

    print('\nOriginal File Content:')
    with open(myfile) as fd:
        print(fd.read())

    print('\nEncrypted File Content:')
    with open(encfile, 'rb') as fd:
        print(fd.read())

    print('\nDecrypted File Content')
    with open(decfile, 'rb') as fd:
        print(fd.read().decode())


if __name__ == '__main__':
    main()
    
'''

Original File Content:
Robin Monroe (Anne Heche) is a New York City journalist who works for Dazzle, a fashion magazine. She is invited by her boyfriend Frank (David Schwimmer) to spend a week holidaying with him on the island paradise of Makatea, in the South Pacific. The final leg of their journey to Makatea is in a dilapidated de Havilland Canada DHC-2 Beaver, piloted by middle-aged American Quinn Harris (Harrison Ford). They are accompanied by Quinn's girlfriend and co-pilot Angelica (Jacqueline Obradors). On their first night on the island, Frank proposes to Robin, who happily accepts. At a bar, a drunken Quinn makes a move on Robin, which she rejects as Frank appears.

Encrypted File Content:
b'\xcc\x92\xb2\x946\x95\xad\xa8\xcf:\x96\xbf\xa1@\xc5t\xa5\xfe\xe8\xca\xfdCL\xc1[\xb6y5%\x91M\xdd\x8b\xde\xfe\x00\x91\xf7Wp\x81\xcfZiC\'f5\xafS\xa5\xdfd\xec\xae\xff5\xb5Q\xd6\xfa\x1b\xa7\xcd\x08\xd8rF\xed\xd0\xcb:\x1b\x02V\x14UaR\xa3\x10a@\xcb\x86\x0bs\x8c[\x1d\xa9\xce\xaa\xf3\x85\x16\xc6\xf9>\xdb\xb03\xb4~\x165\x96\x04\t\x0cvj`\x0b\n\x9f\xd2\xb9\x8f\xbeO\x85\xc6\x96Mw\x00\x96Q\xa7\n\x1e){IiA\x15\xe3\xcfu\xe6\x08\xac\xd3\x9d\x14\x93Bv:\xd0\tJ\xe3\xfd!~\x7f\xe4\x98\xc4\xc3\xa1a\xd5\xee\x0e",\x96\xb0\x86N\xf1\xc6v]\xd1\xf2\xaf\x96[\xcd\xb2\xe7(\xfeq&\xde\xdd\th\xe1\xb2>\x99f\x8c\xf7^M\x8a;%l\x80*\x00\xcd^#KM\xc8\r\x10\xea\xbc\xcc\ryo2f\xa0\x08QQ\xd7\xe6 k\xa1\x0ftL\x91\'\xce\xe4\x06\xf9\xfa\x95\xb5\x04\xf0\xa5u\xa8\x9f\xf8{\x14\xd1`G\'\xad5\xe0C\x8b\x1bZ_\x9a,0\xfc\x01\x18\x86\x9dG3\xc6\xfb\xbf\x97\xdfAk\xf2\x87g0\xac5\x17\xbc\x8c/\x0f\x00\xde\x867\x03\xed\x99\xb2\xee#\xec\x08\x11\xf3\x8e\n\xe6%\x04\xdfS\xe6[,7\x83\xe6[\xc9\xafU\x15@\xc1\xc0\x83\'\x87"dm@\xfbpuFn_\x1a\xd2\xe9}V\xfb\x84x#\xb3\x85\xdb\xd5\r\x0f\x80\xc8\xc4\x90\x98\xa6\xcdh\xd9\x16\xbe\xbd\x82D\x94\xad\xf5\x84\x88\x83D\xbe%\x90\xa8\x1f\x05l\xbchC\x1aY\x9b\x826\x88\xc39t7\xaf\xa2Tq\xf1e7^\xecy\xff\xd6\xed|\xc2\xec\xc6\x05\xdd\xe8\x9e\xe7t\xe9Xa\xa7z%\xd0]m\xf4\x15\xdf\xffF\x0f\x08rg\x1f\xbc\nn\xdb1\x1c\xfa\x0e\xb8\xaf\xc0F\xf6\x85}Yq\xef\xd9\xf9\xaa\xf1\xf8UY[&*\x96\xd7/\xcf\xcf\xa6\xbeeT\xe2^\xd5o\xe4\xb9\x1ae\xb2\xa4\xd13s\x87\\^\xfb\x9ciJ]1\x1d\x81\x89\x8f\xbdv +\xbc\x91\xf9\x99a\xcde\xe8.{Ie\xf0\xbe7v&+d:\xa5J\xdc\xabX4\xfcx0\xbf4\xec\x9c\xe1\x13\xf7q\x11\x8c\x8d\x94\xf0\xdeMS3\xd2\x0f@\x7f`\x93(\x8c$$\xb4\xa6\xc6\xb7B\xd3\xc1\xb7D\xee\xca\xc7h\xd7\xb1\xbe\xf4\xfbQ\x12\x9c\x9309mQ\xeb\xe7\x83&\x98l\x1b\xc4\x18\xa19\xd0\xb8\xec\xec\x0ee\xa1\xf2X\xe0,\xe1\x8c\xb5\x18\x9f\xf5&o\x0f)P\xf7\xb1\xa0\xefv\x08\x16\x0b\x9e\x1b\x97B\x87\xe2i}\xa0Xcv\xed\x0f\xef^\xa9;\xf2\xd4m\xb2<\x0e\x1b\xdeb\x82\xd8\xbdQ\xd4H\xbd\xfc\x8d\xaf^\xcd\n'

Decrypted File Content
Robin Monroe (Anne Heche) is a New York City journalist who works for Dazzle, a fashion magazine. She is invited by her boyfriend Frank (David Schwimmer) to spend a week holidaying with him on the island paradise of Makatea, in the South Pacific. The final leg of their journey to Makatea is in a dilapidated de Havilland Canada DHC-2 Beaver, piloted by middle-aged American Quinn Harris (Harrison Ford). They are accompanied by Quinn's girlfriend and co-pilot Angelica (Jacqueline Obradors). On their first night on the island, Frank proposes to Robin, who happily accepts. At a bar, a drunken Quinn makes a move on Robin, which she rejects as Frank appears.

'''