Public Key와 Private Key의 역할
Public Key와 Private Key의 역할
디지털 서명(Digital Signature)은 메시지의 무결성을 보장하고, 송신자의 신원을 확인할 수 있는 암호화 기술입니다. 이 과정에서는 공개 키(public key)와 개인 키(private key)를 사용하여 서명을 생성하고, 이를 검증할 수 있습니다. 이 글에서는 Python을 사용해 공개 키와 개인 키를 생성하고, 이 키들로 서명을 생성 및 검증하는 방법을 설명합니다.
1. 공개 키와 개인 키의 역할
- 개인 키 (Private Key): 송신자가 자신만이 알고 있는 비밀 키로, 이 키를 사용해 데이터를 암호화하거나 서명을 생성합니다.
- 공개 키 (Public Key): 수신자가 알고 있는 공개 키로, 이 키를 사용해 개인 키로 생성된 서명을 검증하거나 암호화된 데이터를 복호화합니다.
- 서명 프로세스:
- 송신자는 개인 키로 서명을 생성합니다.
- 수신자는 공개 키로 서명을 검증하여 메시지가 변조되지 않았음을 확인합니다.
공개 키(public key)와 개인 키(private key)는 비대칭 암호화 방식의 핵심 요소입니다. 이 두 가지는 서로 밀접한 수학적 관계를 가지며, 이를 이용해 데이터를 암호화하고 서명을 검증하는 데 사용됩니다. 이 관계는 주로 RSA나 ECC 같은 암호화 알고리즘을 통해 구현되며, 비대칭 키 암호화의 주요 특성은 다음과 같습니다.
a. 공개 키와 개인 키의 역할
- 공개 키 (Public Key): 이름 그대로 누구나 알 수 있는 키입니다. 주로 데이터를 암호화하거나, 개인 키로 생성된 서명을 검증하는 데 사용됩니다.
- 개인 키 (Private Key): 소유자만이 알고 있는 비밀 키입니다. 개인 키는 데이터를 복호화하거나, 서명을 생성하는 데 사용됩니다. 절대로 타인과 공유되지 않아야 합니다. 이 두 키는 한 쌍으로 존재하며, 그 관계는 아래와 같습니다.
b. 공개 키와 개인 키의 수학적 관계
- 비대칭성: 공개 키로 암호화된 데이터는 개인 키로만 복호화할 수 있습니다. 마찬가지로, 개인 키로 서명한 데이터를 공개 키로만 검증할 수 있습니다.
- 수학적 연관성: 공개 키와 개인 키는 수학적으로 연결되어 있지만, 공개 키로부터 개인 키를 유추하기는 매우 어렵습니다. 이는 주로 소인수분해 문제(예: RSA) 또는 타원 곡선 알고리즘(ECC)의 복잡성에 기초하여 설계됩니다.
2. Python에서 RSA 키 쌍 생성 및 서명 생성
cryptography
라이브러리는 Python에서 공개 키 기반 암호화를 다루기 위한 인기 있는 라이브러리입니다. 이를 이용해 RSA 키를 생성하고 서명을 만드는 방법을 설명하겠습니다.
2.1. cryptography
라이브러리 설치
먼저, cryptography
라이브러리를 설치합니다.
pip install cryptography
2.2. RSA 키 쌍 생성
RSA 키 쌍을 생성하려면 개인 키와 공개 키를 생성해야 합니다.
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives.asymmetric import rsa
# RSA 키 쌍 생성
= rsa.generate_private_key(
private_key =65537,
public_exponent=2048,
key_size=default_backend()
backend
)
= private_key.public_key()
public_key
# 개인 키와 공개 키 생성 완료
2.3. 메시지에 서명 생성
이제 생성된 개인 키로 메시지에 서명을 추가합니다. 서명은 메시지의 해시 값에 대해 개인 키로 암호화한 것입니다.
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import padding
# 서명할 메시지
= b"A message I want to sign"
message
# 개인 키로 서명 생성
= private_key.sign(
signature
message,
padding.PSS(=padding.MGF1(hashes.SHA256()),
mgf=padding.PSS.MAX_LENGTH
salt_length
),
hashes.SHA256()
)
print("Signature:", signature)
위 코드에서 메시지의 해시 값은 SHA-256 알고리즘을 사용하여 계산되며, PSS
패딩 방식을 통해 서명이 안전하게 처리됩니다.
2.4. 서명 검증
서명이 올바른지, 즉 메시지가 변조되지 않았는지 확인하기 위해 공개 키로 서명을 검증할 수 있습니다.
# 공개 키로 서명 검증
try:
public_key.verify(
signature,
message,
padding.PSS(=padding.MGF1(hashes.SHA256()),
mgf=padding.PSS.MAX_LENGTH
salt_length
),
hashes.SHA256()
)print("서명 검증 성공: 메시지가 변경되지 않았습니다.")
except Exception as e:
print("서명 검증 실패:", e)
3. 공개 키와 개인 키 저장 및 로드
생성된 공개 키와 개인 키를 파일에 저장하고, 나중에 다시 불러올 수 있습니다.
3.1. 개인 키 저장
from cryptography.hazmat.primitives import serialization
# PEM 형식으로 개인 키를 저장
with open("private_key.pem", "wb") as key_file:
key_file.write(
private_key.private_bytes(=serialization.Encoding.PEM,
encodingformat=serialization.PrivateFormat.TraditionalOpenSSL,
=serialization.NoEncryption() # 암호화를 원하면 비밀번호 설정 가능
encryption_algorithm
) )
3.2. 공개 키 저장
# PEM 형식으로 공개 키 저장
with open("public_key.pem", "wb") as key_file:
key_file.write(
public_key.public_bytes(=serialization.Encoding.PEM,
encodingformat=serialization.PublicFormat.SubjectPublicKeyInfo
) )
3.3. 저장된 키 로드
저장된 키는 다음과 같이 다시 로드할 수 있습니다.
개인 키 로드
with open("private_key.pem", "rb") as key_file:
= serialization.load_pem_private_key(
private_key
key_file.read(),=None,
password=default_backend()
backend )
공개 키 로드
with open("public_key.pem", "rb") as key_file:
= serialization.load_pem_public_key(
public_key
key_file.read(),=default_backend()
backend )