파이썬 실습/암호화프로그램만들기

파이썬 암호화 프로그램 만들기 - 4. 양방향 암호화 - 비대칭키(공개키) 방식

파기차차 2022. 11. 19. 08:58
728x90
반응형
SMALL
반응형
ㅁ 개요

 

O 프로그램 소개

 

 - 이번 프로그램은 이전글(2022.11.15 - [파이썬 실습/암호화프로그램만들기] - 파이썬 암호화 프로그램 만들기 - 3. 양방향 암호화 - 대칭키(비공개키) 방식)에 이은 4번째 글로 양방향 암호화 - 비대칭키(공개키) 방식에 대하여 설명합니다.

 

(본 블로그의 내용은 유튜브 동영상(

파이썬 암호화 프로그램 만들기-1.소개편(making Encryption program byPython 4. Public key encryption-1.intro)

파이썬 암호화 프로그램 만들기-2.키생성(making Encryption program byPython 4. Public key encryption-2.make key)

파이썬 암호화 프로그램 만들기-3.암복호화(making Encryption program byPython 4. Public key encryption-3.enc&dec mess)

)에서 더욱 자세히 보실 수 있습니다.)

 

 

 

 - 암호화 알고리즘으로는 RSA, ECC, 전자서명 등이 존재하나, 여기서는 가장 유명하고 널리 사용되는 RSA를 기준으로  설명합니다.

 

 - 공개키 암호화 방식의 가장 대표적인 RSA암호화 알고리즘은 하나의 키가 아닌 2개의 키가 필요하며, 이는 대칭키 방식에서 필연적으로 발생하는 문제점, 즉, 키관리(즉, 키를 어떻게 안전하게 상대방에게 넘겨줄지..) 문제를 해결하기위해 나타난 천재적인 방식입니다.

 

정말 기가막힌 아이디어로 키를 안전하게 상대방에게 넘겨 줄 수 있는 이 방법에 대한 설명을 위해서는 상당한 시간이 필요하므로, 이에 대한 상세한 내용은 아래 링크에서 세상에서 가장 쉬운 설명을 들으실 수 있습니다.

(개인적으로 이 어려운 내용을 이렇게 쉽게 설명하는 곳은 처음 봤습니다. 감동(소름 주의!!)받아서 이렇게 링크로 공유 드립니다.)

https://www.youtube.com/watch?v=MR4sCU82tgo (암호학1-4.1 양방향 암호화 - 비대칭키(공개키 방식) - 기밀성을 위해서 사용하기, 생활코딩)

 

 

 

O 완성된 프로그램 실행 화면
 

 

 - 최종 완성된 프로그램의 결과화면은 아래와 같습니다.
 

(1) 프로그램을 실행시키면 프로그램 내부적으로 1.키 생성, 2.퍼블릭키로 메시지를 암호화를 한 후, 3.프라이빗키로 암호화된 메시지를 복호화 합니다.

아래에서는 원본 메시지 'this is crypto'를 미리 생성된 퍼블릭키로 암호화하여 암호문( b'3\x01`\x83\xb8\x8f\x85\xdbQo\x10Oy\x00\xf5\x14\x08E\x1f\xa5B\xf0\x08/\xd2\x05\xc6\xce\xdb\xfd\xcb\x13o\xd0A$\x85@\xb1v1<\xcd\xdb>\xca2\x1f\xb9\x9a\xfdoH\\\x89\xebA0\xf4\x8e[\xa2\xc5\x08\x8e\x06\x02+\x0c\xe8\x90\x17\xb0\x05j9\xa06\xec\xc6\xe9\xb3\x1ds#\xfb\xe8K\xee\x16\xea\x8bo&\x1a\xfb\xae\'B\x02\xe9sP\x9e\x18J\x16{\x0b6\xf9WN\xf3\x7f|\xabDp\xcekK\x1f\x8c\xce\x85\x9c\xe0m\xb4\xef}\\RU\x88\x0b\xd5\x1a\xb8\x82\xab8\xbc\xc2\x18@RNn&\xd3\xf0\\\x1d\xb5)\xfb\x0c\xb6n\x17\x15kl.EC\xe3\x07\x05\xe8,\x13\xb6*\xad ,\xfc\x7f\xbej\xb2%\xc3\xb4\xad\xd4p\x1bj\xcf\xe3\xe4\x15\xa7Z\x9d\xe9"\xf1\xb7\xf2\xf3\x13\x16\x83\xf6\x99\xc1\x86\\&\xaf7\xa1B\xd9\xc7E\xa6\x82D\xefg8\xde\xaa\x83$\x10^\x1f3\xdb\xc8\xc6\xdd\x8b\x0f7\xa5Vxc\x1c4\x95\xbd\x16\xc5\xbe\x1b\xc3\xe4' )을 만들었고, 이후 이 암호문을 미리 생성한 프라이빗키로 복호화하여 원문과 동일 한 결과인 b'this is crypto' 을 만들어 냈습니다.

 

 

 

 

 

 


 

O 시작전 준비 사항

 

 

 - 프로그램을 실행하기 위해서는 해시 모듈이 필요합니다. 아래와 같이 임포트 해줍니다.

 

import base64
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP

 

 

***에러 발생시 조치 사항(에러가 없는 경우 안보셔도 됩니다.)

--------------------------------------------------------------------------------------

만일 아래와 같이 에러 발생 시

ModuleNotFoundError: No module named 'Crypto'

 

pip install pycrypto <-- 현재 이 모듈은 더 이상 안전하지 않아 설치 되지 않음
pip install pycryptodome <-- 이 모듈을 설치

 

 

위의 모듈 설치 후에도 계속 동일한 에러 발생 시

ModuleNotFoundError: No module named 'Crypto'


아래 부분을 에서 와 같이 수정
from Crypto.cipher import PKCS1_OAEP # 소문자를

 

이렇게 수정

from Crypto.Cipher import PKCS1_OAEP # 대문자로 수정

--------------------------------------------------------------------------------------

 

 

여기까지 이상없이 되셨다면 이제 우리는 다음 단계로 넘어갈 준비가 되었습니다.


 

ㅁ 세부 내용
 
 
O 완성된 소스

 

 

 

소스 1.make_key.py : 공개키 및 프라이빗 키 생성

import base64
from Crypto.PublicKey import RSA
# from Crypto.cipher import PKCS1_OAEP # 암호화를 위해 사용(퍼블릭키 시스템)

# key 생성 및 저장
def make_key():
    pr_key = RSA.generate(2048) # 2048길이의 키 생성
    print(pr_key)
    pu_key = pr_key.public_key()
    print(pu_key)

    pr_file = open('pr.key','wb')
    pr_file.write(pr_key.export_key('PEM'))
    pr_file.close()

    pu_file = open('pu.key', 'wb')
    pu_file.write(pu_key.export_key('PEM'))
    pu_file.close()

make_key()

 

 

 

 

소스 2.encrypt_msg.py : 퍼블릭키로 메시지를 암호화

 

 

import base64
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP # 암호화를 위해 사용(퍼블릭키 시스템), Crypto.cipher -> Crypto.Cipher로 바꿔 줘야 함, 이거 찾는데 하루 걸림 ㅠㅠ

# key 생성 및 저장
def make_key():
    pr_key = RSA.generate(2048) # 2048길이의 키 생성
    print(pr_key)
    pu_key = pr_key.public_key()
    print(pu_key)

    pr_file = open('pr.key','wb')
    pr_file.write(pr_key.export_key('PEM'))
    pr_file.close()

    pu_file = open('pu.key', 'wb')
    pu_file.write(pu_key.export_key('PEM'))
    pu_file.close()

# make_key()


# 메시지 암호화
def encrypt_msg(msg, key):
    tool = PKCS1_OAEP.new(key)
    msg_enc = tool.encrypt(msg)

    return msg_enc

# 메시지 복호화
def decrypt_msg(msg, key):
    tool = PKCS1_OAEP.new(key)
    msg_dec = tool.decrypt(msg)

    return msg_dec

# 파일에서 키 가져오기
def get_key(path):
    fr = open(path, 'rb')
    key = RSA.importKey(fr.read())

    return key

# 메인 함수
def main():
    msg = 'hi my name is aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' # 최대 86자까지 암호화 가능, 암호화 하면 무조건 128비트로 변환됨
    pu_key = get_key('pu.key')
    msg_enc = encrypt_msg(msg.encode(), pu_key)

    print("원문", msg)
    print("암호화 길이", len(msg_enc))
    print("암호화", msg_enc)



main()

 

 

 

 

소스 3.decrypt_msg.py : 퍼블릭 키로 암호화된 메시지를 프라이빗키로 복호화

 

 

import base64
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP # 암호화를 위해 사용(퍼블릭키 시스템), Crypto.cipher -> Crypto.Cipher로 바꿔 줘야 함, 이거 찾는데 하루 걸림 ㅠㅠ

# key 생성 및 저장
def make_key():
    pr_key = RSA.generate(2048) # 2048길이의 키 생성
    print(pr_key)
    pu_key = pr_key.public_key() # 생성된 프라이빗키로 퍼블릭키 생성
    print(pu_key)

    pr_file = open('pr.key','wb')
    pr_file.write(pr_key.export_key('PEM')) # 프라이빗 키를 파일로 저장
    pr_file.close()

    pu_file = open('pu.key', 'wb')
    pu_file.write(pu_key.export_key('PEM')) # 퍼블릭 키를 파일로 저장
    pu_file.close()

# make_key()


# 메시지 암호화
def encrypt_msg(msg, key):
    tool = PKCS1_OAEP.new(key)
    msg_enc = tool.encrypt(msg)

    return msg_enc

# 메시지 복호화
def decrypt_msg(msg, key):
    tool = PKCS1_OAEP.new(key)
    msg_dec = tool.decrypt(msg)

    return msg_dec

# 파일에서 키 가져오기
def get_key(path):
    fr = open(path, 'rb')
    key = RSA.importKey(fr.read())

    return key

# 메인 함수
def main():
    msg = 'this is crypto' # 원본 메시지
    pu_key = get_key('pu.key') # 퍼블릭 키를 가져옴
    msg_enc = encrypt_msg(msg.encode(), pu_key) # 퍼블릭키로 메시지를 암호화

    print("원문", msg)
    print("암호화 길이", len(msg_enc))
    print("암호화", msg_enc)
    
    pr_key = get_key('pr.key') # 프라이빗 키를 가져옴
    msg_dec = decrypt_msg(msg_enc, pr_key) # 퍼블릭키로 암호화된 메시지를 프라이빗키로 복호화
    print("복호화", msg_dec)

main()

 

 

 

 

O 소스 다운로드 및 실행
 
 - 소스파일 다운로드 후 cmd 또는 파워쉘 등에서 아래와 같이 실행하시기 바랍니다.
 
 
 > python 1.make_key.py
 
 > python 2.encrypt_msg.py
  
 > python 3.decrypt_msg.py

 

 


 
 
O 소스 분석

 

1.pr_key = RSA.generate(2048) <-- 2048길이의 프라이빗 키 생성
2.pu_key = pr_key.public_key() <-- 생성된 프라이빗키로 퍼블릭키 생성
3.pr_file.write(pr_key.export_key('PEM')) <-- 프라이빗 키를 파일로 저장
4.pu_file.write(pu_key.export_key('PEM')) <-- 퍼블릭 키를 파일로 저장
5.tool = PKCS1_OAEP.new(key) <-- RSA암호화 알고리즘 적용
6.msg_enc = tool.encrypt(msg) <-- RSA암호화 알고리즘으로 메시지암호화
7.msg_dec = tool.decrypt(msg) <-- RSA암호화 알고리즘으로 메시지복호화
7.msg_enc = encrypt_msg(msg.encode(), pu_key) <-- 퍼블릭키로 메시지를 암호화 하도록 encrypt_msg()함수 호출
8.key = RSA.importKey(fr.read()) <-- 파일에서 키 가져오기(읽어오기)
9.pu_key = get_key('pu.key') <-- 퍼블릭 키를 가져옴
10.pr_key = get_key('pr.key') <-- 프라이빗 키를 가져옴
11.msg_dec = decrypt_msg(msg_enc, pr_key) <-- 퍼블릭키로 암호화된 메시지를 프라이빗키로 복호화

 


 

O 주요 내용

 

소스 1.make_key.py : 공개키 및 프라이빗 키 생성

1.아래 소스와 같이 RSA암호화 알고리즘 모듈을 이용하여 2048길이의 프라이빗 키와 공개키를 생성 후 파일에 저장합니다.

 

 

 2.실행하면 프라이빗키와 공개키가 생성됩니다.

 

 

 3. 폴더를 보니 잘 생성된 것을 확인할 수 있습니다.(pr.key, pu.key)

 

 4.프라이빗키를 텍스트 편집기로 열어보니 이렇게 생겼습니다.

 

 

소스 2.encrypt_msg.py : 퍼블릭키로 메시지를 암호화

1.위에서 만든 공개키를 이용하여 메시지를 암호화 합니다.

 

 

 2. 프로그램 실행 결과 메시지가 256개의 길이로 잘 암호화 된것을 확인할 수 있습니다.

 

 

 

 

 

 

소스 3.decrypt_msg.py : 퍼블릭키로 암호화된 메시지를 프라이빗키로 복호화

1.이제 위에서 공개키로 암호화한 메시지를 복호화 합니다.

 

 

 

 2. 프로그램 실행 결과 공개키로 암호화된 메시지가 이전 원문 메시지로 잘 복호화 된 것을 확인할 수 있습니다.

 

 

 

 

 

 

 


 

ㅁ 정리
 
O 우리가 배운 내용
 
 - 오늘은 암호화의 내용 중 양방향 암호화 - 공개키 암호화 방식에 대하여 공부해 보았습니다.
 
 
 - 오늘 우리가 배운 내용을 간단히 정리해 보면 아래와 같습니다.
 
 > 1. 키생성 : 공개키 및 프라이빗 키 생성, 소스 1.make_key.py
 > 2. 공개키로 암호화 : 퍼블릭키로 메시지를 암호화, 소스 2.encrypt_msg.py 
 > 3. 개인키로 복호화: 퍼블릭 키로 암호화된 메시지를 프라이빗키로 복호화, 소스 3.decrypt_msg.py
 
 

 

오늘은 여기까지이며, 위의 내용이 유익하셨다면, 좋아요와 구독 부탁드립니다.

 

 

감사합니다.

728x90
반응형
LIST