G허니 2024. 8. 11. 20:19

 

전자서명은 디지털 데이터의 무결성과 인증을 보장하기 위해 사용되는 기술입니다. 주로 비대칭 암호화 방식에 기반하여 작동하며, 두 개의 키(개인키와 공개키)를 사용하여 서명과 검증 과정을 수행합니다.

 

  1. 무결성: 전자서명을 통해 서명된 데이터가 전송 중에 변경되지 않았음을 보장합니다.
  2. 인증: 서명자는 개인키를 사용하여 서명을 생성하므로, 서명된 데이터는 해당 서명자의 소유임을 증명합니다.
  3. 부인 방지: 서명자는 서명된 메시지를 부인할 수 없으며, 이는 법적 효력을 가질 수 있습니다.
타원 곡선 암호화(ECC)를 사용하여 전자서명을 구현

 

import os
import random
import time
import hashlib

# 타원 곡선의 파라미터
p = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F
G = [0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798,
     0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8]
a = 0
b = 7

def get_private_key():
    """개인키 생성 함수"""
    while True:
        random_str = os.urandom(256 // 8) + str(random.random()).encode() + str(time.time()).encode()
        random_num = hashlib.sha256(random_str).digest()
        private_key = int.from_bytes(random_num, 'big')
        if private_key < p:
            break
    return private_key

def euclidian(b, n):
    """유클리드 알고리즘을 사용하여 역원을 찾는 함수"""
    r1 = n
    r2 = b if b > 0 else b + n
    t1 = 0
    t2 = 1
    while r2 > 0:
        q = r1 // r2
        r = r1 - q * r2
        r1 = r2
        r2 = r
        t = t1 - q * t2
        t1 = t2
        t2 = t
    if r1 == 1:
        return t1 if t1 > 0 else t1 + n
    else:
        return None

def euclidean_algorithm(a, b):
    """두 수의 최대공약수를 구하는 유클리드 알고리즘"""
    if b == 0:
        return (a, 1, 0)
    else:
        gcd, x, y = euclidean_algorithm(b, a % b)
        return (gcd, y, x - (a // b) * y)

def find_inverse(a, p):
    """모듈로 역원을 찾는 함수"""
    gcd, x, y = euclidean_algorithm(a, p)
    if gcd == 1:
        return x % p
    else:
        return None

def add(point1: list, point2: list):
    """타원 곡선 위의 두 점을 더하는 함수"""
    if point1 == point2:
        w = (3 * point1[0] ** 2 + a) * euclidian((2 * point1[1]), p) % p
    else:
        w = (point2[1] - point1[1]) * euclidian(point2[0] - point1[0], p) % p
    if w < 0:
        w += p
    x3 = (w ** 2 - point1[0] - point2[0]) % p
    y3 = (w * (point1[0] - x3) - point1[1]) % p
    if x3 < 0:
        x3 += p
    if y3 < 0:
        y3 += p
    point3 = [x3, y3]
    return point3

def double_and_add(x, G: list):
    """스칼라 곱셈을 수행하는 함수"""
    binary = bin(x)
    K = G
    for i in range(3, len(binary)):
        if binary[i] == '1':
            K = add(add(K, K), G)
        else:
            K = add(K, K)

    return tuple(K)

# 서명 생성 및 검증 함수
def sign(M, d):
    """메시지를 서명하는 함수"""
    while True:
        r = random.randint(1, q-1)
        x1, y1 = double_and_add(r, e1)
        S1 = x1 % q

        if S1 == 0:
            continue
        h = int.from_bytes(hashlib.sha256(M.encode()).digest()) % q
        S2 = ((h + d * S1) * find_inverse(r, q)) % q
        if S2 == 0:
            continue
        
        return S1, S2

def verify(M, S1, S2, e2):
    """서명을 검증하는 함수"""
    h = hashlib.sha256(M.encode()).hexdigest()
    S2_inverse = find_inverse(S2, q)
    A = (int(h, 16) * S2_inverse) % q
    B = (S1 * S2_inverse) % q

    x, y = add(double_and_add(A, e1), double_and_add(B, e2))

    return x % q == S1 % q

if __name__ == "__main__":
    d = get_private_key()  # 개인키
    e2 = double_and_add(d, G)  # 공개키

    M = input("메시지? ")
    S1, S2 = sign(M, d)  # 서명 생성
    print("1. Sign:")
    print("\tS1 =", hex(S1))
    print("\tS2 =", hex(S2))

    print("2. 정확한 서명을 입력할 경우:")
    if verify(M, S1, S2, e2):
        print("검증 성공")
    else:
        print("검증 실패")

    print("3. 잘못된 서명을 입력할 경우:")
    if verify(M, S1-1, S2-1, e2):
        print("검증 성공")
    else:
        print("검증 실패")

 

  1. 모듈 임포트: 필요한 모듈을 가져옵니다. os, random, time, hashlib는 난수 생성 및 해싱에 사용됩니다.
  2. 타원 곡선 파라미터: p, G, a, b는 타원 곡선의 파라미터입니다. 이들은 ECC의 특정 곡선을 정의합니다.
  3. 개인키 생성: get_private_key() 함수는 안전한 개인키를 생성합니다. 랜덤한 문자열을 해싱하여 개인키를 생성하고, 조건에 맞는지 확인합니다.
  4. 유클리드 알고리즘: euclidian 및 euclidean_algorithm 함수는 모듈로 역원을 찾기 위한 최대공약수(GCD)를 계산합니다.
  5. 점 덧셈: add() 함수는 타원 곡선 위에서 두 점을 더하는 기능을 수행합니다.
  6. 서명 생성: sign() 함수는 주어진 메시지 M과 개인키 d를 사용하여 서명 (S1, S2)를 생성합니다.
  7. 서명 검증: verify() 함수는 주어진 메시지와 서명을 검증하여 서명이 올바른지 확인합니다.

 

깃허브

https://github.com/Ghoney99/Network-Secure-and-BlockChain