디지털 서명 (digital signature)

디지털 서명은 전자 문서나 메시지의 진위성, 무결성, 그리고 부인 방지를 보장하기 위해 사용되는 암호화 기술
이는 실제 서명의 디지털 버전으로 볼 수 있다.

장점:

  1. 높은 보안성: 암호화 기술을 사용하여 위조가 매우 어렵다.
  2. 효율성: 종이 기반 서명에 비해 빠르고 비용 효율적이다.
  3. 글로벌 접근성: 지리적 제약 없이 사용 가능하다.

기본 원리 예시:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import padding, rsa

class DigitalSignature:
    def __init__(self):
        # 키 쌍 생성 (실제 사용시에는 더 큰 키 크기 사용)
        self.private_key = rsa.generate_private_key(
            public_exponent=65537,
            key_size=2048
        )
        self.public_key = self.private_key.public_key()
    
    def sign_document(self, document):
        """문서에 대한 디지털 서명 생성"""
        # 문서의 해시값 계산 후 서명
        signature = self.private_key.sign(
            document.encode(),
            padding.PSS(
                mgf=padding.MGF1(hashes.SHA256()),
                salt_length=padding.PSS.MAX_LENGTH
            ),
            hashes.SHA256()
        )
        return signature
    
    def verify_signature(self, document, signature):
        """서명 검증"""
        try:
            self.public_key.verify(
                signature,
                document.encode(),
                padding.PSS(
                    mgf=padding.MGF1(hashes.SHA256()),
                    salt_length=padding.PSS.MAX_LENGTH
                ),
                hashes.SHA256()
            )
            return True
        except:
            return False

주요 특징

  1. 인증: 문서나 메시지가 실제로 서명자에 의해 생성되었음을 확인한다.
  2. 무결성: 전송 과정에서 데이터가 변경되지 않았음을 보장한다.
  3. 부인 방지: 서명자가 나중에 서명 사실을 부인할 수 없게 한다.

작동 과정

  1. 해시 생성 단계: 해시 함수를 사용하여 문서의 고유한 해시값을 생성한다.

    1
    2
    3
    4
    5
    
    def create_document_hash(document):
        """문서의 해시값 생성"""
        hasher = hashes.Hash(hashes.SHA256())
        hasher.update(document.encode())
        return hasher.finalize()
    
  2. 서명 생성 단계: 서명자의 개인키로 해시값을 암호화하여 서명을 생성한다.

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    
    def detailed_signing_process(private_key, document):
        """서명 과정의 세부 단계 표시"""
        # 1. 문서 해시 생성
        document_hash = create_document_hash(document)
    
        # 2. 해시값을 개인키로 암호화하여 서명 생성
        signature = private_key.sign(
            document_hash,
            padding.PSS(
                mgf=padding.MGF1(hashes.SHA256()),
                salt_length=padding.PSS.MAX_LENGTH
            ),
            hashes.SHA256()
        )
    
        return signature, document_hash
    
  3. 서명 검증 과정: 수신자는 서명자의 공개키를 사용하여 서명을 검증한다.

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    
    def detailed_verification_process(public_key, document, signature):
        """검증 과정의 세부 단계 표시"""
        try:
            # 1. 받은 문서의 해시값 계산
            received_hash = create_document_hash(document)
    
            # 2. 서명을 공개키로 복호화하여 원본 해시값 추출
            # 3. 두 해시값 비교
            public_key.verify(
                signature,
                document.encode(),
                padding.PSS(
                    mgf=padding.MGF1(hashes.SHA256()),
                    salt_length=padding.PSS.MAX_LENGTH
                ),
                hashes.SHA256()
            )
            return True
        except:
            return False
    

보안 고려사항과 모범 사례

  1. 키 관리
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
class SecureKeyManagement:
    def __init__(self):
        self.key_store = {}
        
    def generate_new_key_pair(self):
        """새로운 키 쌍 생성"""
        private_key = rsa.generate_private_key(
            public_exponent=65537,
            key_size=4096  # 충분히 큰 키 크기 사용
        )
        return private_key, private_key.public_key()
        
    def store_private_key(self, key_id, private_key, password):
        """개인키 안전한 저장"""
        # 실제 구현에서는 암호화하여 저장
        encrypted_key = self.encrypt_key(private_key, password)
        self.key_store[key_id] = encrypted_key
  1. 타임스탬프 통합
1
2
3
4
5
6
7
8
9
class TimestampedSignature:
    def __init__(self):
        self.signer = DigitalSignature()
        
    def sign_with_timestamp(self, document):
        """타임스탬프가 포함된 서명 생성"""
        timestamp = str(time.time())
        content_with_timestamp = f"{document}|{timestamp}"
        return self.signer.sign_document(content_with_timestamp), timestamp

응용 분야

  1. 전자 계약 시스템
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class ElectronicContract:
    def __init__(self):
        self.signer = DigitalSignature()
        self.contract_content = ""
        self.signatures = {}
        
    def create_contract(self, content):
        """계약서 생성"""
        self.contract_content = content
        
    def sign_contract(self, signer_id):
        """계약서 서명"""
        signature = self.signer.sign_document(self.contract_content)
        self.signatures[signer_id] = signature
        
    def verify_all_signatures(self):
        """모든 서명 검증"""
        for signer_id, signature in self.signatures.items():
            if not self.signer.verify_signature(
                self.contract_content, 
                signature
            ):
                return False
        return True
  1. 소프트웨어 패키지 무결성 검증
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
class SoftwarePackageVerification:
    def __init__(self):
        self.signer = DigitalSignature()
        
    def sign_package(self, package_data):
        """소프트웨어 패키지 서명"""
        return self.signer.sign_document(package_data)
        
    def verify_package(self, package_data, signature):
        """패키지 무결성 검증"""
        return self.signer.verify_signature(package_data, signature)
  1. 이메일 보안: 이메일의 진위성을 확인한다.
  2. 블록체인: 트랜잭션의 유효성을 검증한다.
  3. 법적 문서: 전자 계약 등에 사용된다.

실제 응용시 고려할 점들

  1. 해시 알고리즘 선택: SHA-256 이상의 안전한 해시 알고리즘 사용
  2. 키 길이: 충분히 긴 키 길이 사용 (RSA의 경우 최소 2048비트)
  3. 안전한 난수 생성기 사용
  4. 정기적인 키 갱신
  5. 인증서 체인 관리

참고 및 출처