Public Key와 Private Key의 역할

Public Key와 Private Key의 역할

Python
Public Key와 Private Key의 역할
Author

gabriel yang

Published

September 30, 2024

Public Key와 Private Key의 역할

디지털 서명(Digital Signature)은 메시지의 무결성을 보장하고, 송신자의 신원을 확인할 수 있는 암호화 기술입니다. 이 과정에서는 공개 키(public key)개인 키(private key)를 사용하여 서명을 생성하고, 이를 검증할 수 있습니다. 이 글에서는 Python을 사용해 공개 키와 개인 키를 생성하고, 이 키들로 서명을 생성 및 검증하는 방법을 설명합니다.

1. 공개 키와 개인 키의 역할

  • 개인 키 (Private Key): 송신자가 자신만이 알고 있는 비밀 키로, 이 키를 사용해 데이터를 암호화하거나 서명을 생성합니다.
  • 공개 키 (Public Key): 수신자가 알고 있는 공개 키로, 이 키를 사용해 개인 키로 생성된 서명을 검증하거나 암호화된 데이터를 복호화합니다.
  • 서명 프로세스:
  1. 송신자는 개인 키로 서명을 생성합니다.
  2. 수신자는 공개 키로 서명을 검증하여 메시지가 변조되지 않았음을 확인합니다.

공개 키(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 키 쌍 생성
private_key = rsa.generate_private_key(
    public_exponent=65537,
    key_size=2048,
    backend=default_backend()
)

public_key = private_key.public_key()

# 개인 키와 공개 키 생성 완료

2.3. 메시지에 서명 생성

이제 생성된 개인 키로 메시지에 서명을 추가합니다. 서명은 메시지의 해시 값에 대해 개인 키로 암호화한 것입니다.

from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import padding

# 서명할 메시지
message = b"A message I want to sign"

# 개인 키로 서명 생성
signature = private_key.sign(
    message,
    padding.PSS(
        mgf=padding.MGF1(hashes.SHA256()),
        salt_length=padding.PSS.MAX_LENGTH
    ),
    hashes.SHA256()
)

print("Signature:", signature)

위 코드에서 메시지의 해시 값은 SHA-256 알고리즘을 사용하여 계산되며, PSS 패딩 방식을 통해 서명이 안전하게 처리됩니다.

2.4. 서명 검증

서명이 올바른지, 즉 메시지가 변조되지 않았는지 확인하기 위해 공개 키로 서명을 검증할 수 있습니다.

# 공개 키로 서명 검증
try:
    public_key.verify(
        signature,
        message,
        padding.PSS(
            mgf=padding.MGF1(hashes.SHA256()),
            salt_length=padding.PSS.MAX_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(
            encoding=serialization.Encoding.PEM,
            format=serialization.PrivateFormat.TraditionalOpenSSL,
            encryption_algorithm=serialization.NoEncryption()  # 암호화를 원하면 비밀번호 설정 가능
        )
    )

3.2. 공개 키 저장

# PEM 형식으로 공개 키 저장
with open("public_key.pem", "wb") as key_file:
    key_file.write(
        public_key.public_bytes(
            encoding=serialization.Encoding.PEM,
            format=serialization.PublicFormat.SubjectPublicKeyInfo
        )
    )

3.3. 저장된 키 로드

저장된 키는 다음과 같이 다시 로드할 수 있습니다.

개인 키 로드

with open("private_key.pem", "rb") as key_file:
    private_key = serialization.load_pem_private_key(
        key_file.read(),
        password=None,
        backend=default_backend()
    )

공개 키 로드

with open("public_key.pem", "rb") as key_file:
    public_key = serialization.load_pem_public_key(
        key_file.read(),
        backend=default_backend()
    )
Date Title Author
Jan 1, 3000 전체 카테고리 gabriel yang
Nov 26, 2024 VSCode에서 Python 디버깅 (launch.json 설정) gabriel yang
Nov 23, 2024 Python 설치된 패키지 확인, 설치와 복원하기 gabriel yang
Oct 14, 2024 JSON 파일에서 특정 key의 값 변경 후 저장하는 방법 gabriel yang
Oct 10, 2024 날짜 문자열을 날짜 형식으로 변환하기 gabriel yang
Oct 8, 2024 Request를 통한 JIRA REST API 사용방법 gabriel yang
Oct 8, 2024 Request 라이브러리 사용방법 gabriel yang
Oct 8, 2024 Requests 라이브러리로 베이직 인증 API 호출하기 gabriel yang
Oct 7, 2024 Python으로 SSH를 제어하기 gabriel yang
Oct 7, 2024 Pytest로 테스트하기 gabriel yang
Oct 7, 2024 Pytest 기본적인 테스트 실행 방법 gabriel yang
Oct 7, 2024 Pytest Fixture 개념과 필요성 gabriel yang
Oct 7, 2024 CI 환경에서 Pytest 사용하기 gabriel yang
Oct 7, 2024 파이썬에서 테스트 코드 리팩토링 기법 gabriel yang
Oct 5, 2024 Python os 모듈을 이용한 파일과 폴더 관리 gabriel yang
Oct 5, 2024 Python shutil 모듈을 이용한 파일과 폴더 관리 gabriel yang
Oct 5, 2024 MongoDB 데이터베이스 백업 및 복원 방법 gabriel yang
Oct 5, 2024 Python jira 라이브러리를 이용해 JIRA를 관리하는 방법 gabriel yang
Oct 4, 2024 Python에서 JSON 파일 읽기 및 데이터 활용 gabriel yang
Oct 4, 2024 JSON 데이터 수정하기 gabriel yang
Oct 4, 2024 JSON 파일의 구성요소와 구조 gabriel yang
Oct 4, 2024 Python에서 Git명령 사용하기 gabriel yang
Oct 3, 2024 파이썬으로 클래스 정의하는 방법 gabriel yang
Oct 3, 2024 파이썬의 상속(Inheritance) 이해하기 gabriel yang
Oct 3, 2024 파이썬 클래스의 self 이해하기 gabriel yang
Oct 3, 2024 파이썬에서 추상 클래스(Abstract Class) 사용하기 gabriel yang
Oct 3, 2024 파이썬 클래스 활용 예시 gabriel yang
Oct 3, 2024 파이썬 클래스와 모듈 gabriel yang
Oct 3, 2024 파이썬에서 Lock을 사용하는 이유와 방법 gabriel yang
Oct 2, 2024 Python에서 zip()을 사용하는 이유와 방법 gabriel yang
Oct 2, 2024 파이썬 시퀀스 슬라이싱 gabriel yang
Oct 2, 2024 파이썬에서 Generator를 사용하는 이유와 사용법 gabriel yang
Oct 2, 2024 파이썬의 @property 기능 gabriel yang
Oct 2, 2024 파이썬 시퀀스 언패킹 gabriel yang
Oct 2, 2024 파이썬 데이터 정렬 gabriel yang
Oct 2, 2024 파이썬 딕셔너리 key 예외처리하기 gabriel yang
Oct 2, 2024 파이썬의 defaultdict 사용법 gabriel yang
Oct 2, 2024 파이썬의 try-except 사용법 gabriel yang
Oct 2, 2024 파이썬의 클로저(Clsure) 사용법 gabriel yang
Oct 2, 2024 파이썬의 가변인자 사용법 gabriel yang
Oct 2, 2024 파이썬의 컴프리헨션(Comprehension) 사용법 gabriel yang
Oct 1, 2024 파이썬 가상환경 설정 gabriel yang
Oct 1, 2024 파이썬을 이용한 테스트 자동화 gabriel yang
Oct 1, 2024 파이썬 docstring을 사용하는 이유와 방법 gabriel yang
Oct 1, 2024 파이썬 yield 제너레이터와 효율적인 반복 처리 gabriel yang
Oct 1, 2024 파이썬 데이터 언패킹 gabriel yang
Oct 1, 2024 Python에서 enumerate를 사용하는 이유와 사용 방법 gabriel yang
Sep 30, 2024 Python 설치 및 기본 파이썬 버전 설정 gabriel yang
Sep 30, 2024 Python을 이용한 폴더 전체 복사 방법 gabriel yang
Sep 23, 2024 Python의 @dataclass 데코레이터 gabriel yang
Aug 30, 2024 Python shell명령 수행하기 (Subprocess) gabriel yang
Aug 29, 2024 Google Colab에서 라이브러리 설치하기 gabriel yang
Aug 1, 2024 환경변수 설정하고 Python에서 읽어오기 gabriel yang
Jan 1, 2024 코루틴(coroutine)과 이벤트 루프 gabriel yang
No matching items
Back to BLOG LIST