[카테고리:] 미분류

  • ECDSA_sign 함수 정리

    개요

    ECDSA_sign은 OpenSSL 라이브러리에서 제공하는 저수준 ECDSA 서명 함수로, 주어진 해시 값을 타원곡선 개인 키로 서명하여 DER 인코딩된 결과를 생성한다[1].

    주요 함수 및 기능

    OpenSSL 3.0 기준으로는 deprecated(사용 권장하지 않음)되었으나, 아직 많은 코드에서 사용된다[1].

    함수명설명반환값참고
    ECDSA_size(eckey)eckey로 생성 가능한 최대 DER 서명 크기(바이트)정수 또는 0(오류 시)[1]
    ECDSA_sign(type, dgst, dgstlen, sig, siglen, eckey)해시 dgst(dgstlen 바이트)를 eckey 개인 키로 서명 후 DER로 인코딩하여 sig에 저장1(성공)/0(오류)[1]
    ECDSA_do_sign(dgst, dgstlen, eckey)dgst 해시에 대해 서명 후 ECDSA_SIG 구조체 반환ECDSA_SIG*/NULL[1]
    ECDSA_verify(type, dgst, dgstlen, sig, siglen, eckey)sig의 DER 서명이 dgst 해시에 대해 eckey 공개 키로 유효한지 검증1(유효)/0(무효)/-1(오류)[1]
    ECDSA_do_verify(dgst, dgstlen, sig, eckey)ECDSA_SIG 구조체 형태의 서명을 검증1/0/-1[1]
    ECDSA_sign_setup(eckey, ctx, kinv, rp)서명 연산의 일부를 사전 계산하여 kinv, rp 반환1/0[1]
    ECDSA_sign_ex(type, dgst, dgstlen, sig, siglen, kinv, rp, eckey)kinv, rp를 사용해 서명 연산 수행1/0[1]
    ECDSA_do_sign_ex(dgst, dgstlen, kinv, rp, eckey)sign_ex와 유사, ECDSA_SIG* 반환ECDSA_SIG*/NULL[1]

    파라미터 설명

    • type: 현재 무시되는 값, 항상 0 지정[1].
    • dgst, dgstlen: SHA-256 등으로 해시된 메시지 바이트 배열과 길이[1].
    • sig, siglen: DER 서명을 저장할 버퍼 및 실제 서명 길이 저장 변수[1].
    • eckey: EC_KEY 형식의 개인·공개 키 객체[1].
    • kinv, rp: ECDSA_sign_setup로 사전 계산된 난수 역수 및 점 r 값(고급 사용 시)[1].

    내부 동작 흐름

    1. dgst 해시 값을 입력받음[1].
    2. 랜덤 k 생성(또는 kinv, rp 사용)[1].
    3. 타원곡선 점 곱셈 R = k·G 수행 후 x좌표 r = R.x mod n 계산[2].
    4. $$ s = k^{-1}\,(h + d\cdot r)\bmod n $$ 방정식으로 s 계산[2].
    5. $$(r,s)$$를 ASN.1 DER 형식으로 인코딩해 sig에 저장[1].

    사용 예시

    #include <openssl/ecdsa.h>
    #include <openssl/obj_mac.h>
    
    EC_KEY *eckey = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);  
    EC_KEY_generate_key(eckey);  
    
    unsigned char digest[32] = { /* SHA-256 해시 */ };  
    unsigned char *sig = NULL;  
    unsigned int siglen;  
    
    int buf_len = ECDSA_size(eckey);  
    sig = OPENSSL_malloc(buf_len);  
    if (ECDSA_sign(0, digest, 32, sig, &siglen, eckey) != 1) {  
        /* 오류 처리 */  
    }  
    
    // 검증  
    if (ECDSA_verify(0, digest, 32, sig, siglen, eckey) != 1) {  
        /* 검증 실패 */  
    }  

    위 예시는 ECDSA_size, ECDSA_sign, ECDSA_verify 함수 사용 흐름을 보여준다[1].

    주의 사항

    • Deprecated: OpenSSL 3.0 이후에는 EVP_PKEY_sign/verify 등의 상위 API 사용 권장[1].
    • k값 보안: 난수 k가 노출되면 개인 키가 유출될 수 있으므로, 매 서명마다 안전하게 생성해야 함[3].
    • 메모리 관리: OPENSSL_malloc으로 할당한 버퍼는 사용 후 반드시 해제해야 함.

    이상으로 ecdsa_sign 및 관련 함수의 정의, 동작 원리, 사용법, 주의점을 모두 정리하였다.

    출처
    [1] Elliptic Curve Digital Signature Algorithm – Wikipedia https://en.wikipedia.org/wiki/Elliptic_Curve_Digital_Signature_Algorithm
    [2] ECDSA: Elliptic Curve Signatures https://cryptobook.nakov.com/digital-signatures/ecdsa-sign-verify-messages
    [3] ECDSA 서명 – Crypto 스터디 http://cryptostudy.xyz/crypto/article/4-ECDSA-%EC%84%9C%EB%AA%85
    [4] What Is Elliptic Curve Digital Signature Algorithm? – ECDSA – Cyfrin https://www.cyfrin.io/blog/elliptic-curve-digital-signature-algorithm-and-signatures
    [5] Understanding How ECDSA Protects Your Data. – Instructables https://www.instructables.com/Understanding-how-ECDSA-protects-your-data/
    [6] ECDSA_sign(3ssl) – Arch Linux manual pages https://man.archlinux.org/man/ECDSA_sign.3.en
    [7] ECDSA | Elliptic Curve Digital Signature Algorithm https://learnmeabitcoin.com/technical/cryptography/elliptic-curve/ecdsa/
    [8] OpenSSL ECDSA signature validity – Stack Overflow https://stackoverflow.com/questions/36452829/openssl-ecdsa-signature-validity
    [9] ECDSA_SIG_new(3ssl) – Arch Linux manual pages https://man.archlinux.org/man/core/openssl/ECDSA_SIG_new.3ssl.en
    [10] ECDSA 사용시 Signature 값이 매번 다른 이유 : 네이버 블로그 https://blog.naver.com/PostView.naver?blogId=aepkoreanet&logNo=222621861479