2017-11-06 16 views
0

ASN.1 DER로 인코딩되지 않은 ECDSA 서명이 포함 된 일부 데이터 패킷을 확인하려고합니다.openSSL : r 대신 압축 된 CurvePoint R을 사용하여 원시 데이터에서 ECDSA 서명 가져 오기

openSSL (버전 1.1.0)을 사용하여 필요한 모든 기능을 수행하는 것으로 보입니다.

현재 데이터 패킷에서 서명을 가져오고 있습니다. 서명은 다음과 같다 :

signature shown in Wireshark

tshark를 이런 제품 관련 표시 (마지막 4 바이트 서명의 부분으로 표시되어서는 안된다)

"gn.sh.sig": { 
     "gn.st.pka": "0", 
     "gn.st.eccpointtype": "3", 
     "gn.st.opaque": "1f:f8:ad:a7:fd:99:b2:a8:a2:69:d4:d6:67:e5:ee:5b:3f:8b:e8:7f:49:fc:b4:79:95:98:15:0d:cb:bd:06:3c", 
     "gn.st.opaque": "61:a4:6a:c9:a7:dd:bd:0d:9c:0a:0e:73:db:52:06:bb:79:53:99:51:16:45:45:81:4e:df:94:5c:58:59:40:14" 
    } 

인코딩은 ETSI TS 103 097 v1.2.1

opaqueECC Point type과 함께 EccPoint는 R이고 두 번째 필드 opaques입니다.

첫 번째 단계는 openSSL에서 서명을 만들어 데이터를 가져 오는 것입니다.

내 코드 (오류 처리가 크기를 줄이기 위해 제거) 다음과 같습니다

#include <openssl/conf.h> 
#include <openssl/evp.h> 
#include <openssl/err.h> 
#include <openssl/ec.h> 
#include <openssl/ecdsa.h> 
#include <openssl/bn.h> 

#include <stdlib.h> 
#include <stdio.h> 
#include <stdint.h> 
#include <string.h> 

void verify_signature(void) 
{ 
    int res; 

    // Which value is correct for r-part? 
    static const char sig_r_hex[] = "1ff8ada7fd99b2a8a269d4d667e5ee5b3f8be87f49fcb4799598150dcbbd063c"; 
    static const char sig_s_hex[] = "61a46ac9a7ddbd0d9c0a0e73db5206bb79539951164545814edf945c58594014"; 

    BN_CTX *bn_ctx = BN_CTX_new(); 
    BN_CTX_start(bn_ctx); 

    // Create signature and import from packet. 
    BIGNUM *bn_r = BN_CTX_get(bn_ctx); 
    BIGNUM *bn_s = BN_CTX_get(bn_ctx); 

    res = BN_hex2bn(&bn_r, sig_r_hex); 
    res = BN_hex2bn(&bn_s, sig_s_hex); 

    ECDSA_SIG *signature = ECDSA_SIG_new(); 
    res = ECDSA_SIG_set0(signature, bn_r, bn_s); 
    printf("ECDSA_SIG_set0(): %d\n", res); 

    // ... 
    // Create hash of message and verify signature with public key 
    //... 
} 

int main(int arc, char *argv[]) 
{ 
    ERR_load_crypto_strings(); 
    OpenSSL_add_all_algorithms(); 
    OPENSSL_config(NULL); 

    verify_signature(); 

    EVP_cleanup(); 
    CRYPTO_cleanup_all_ex_data(); 
    ERR_free_strings(); 
    return 0; 
} 

는 내가 현재 실종 것은 내가 제대로 값 R을 처리하는 방법입니다. 압축 된 CurvePoint의 어떤 부분을 r으로 사용하여 서명을 초기화해야합니까? y 부분의 압축을 풀어야합니까? 압축 된 y 값에 대한 표시를 추가해야합니까?

힌트를 환영합니다.

편집 : IEEE1609.2와 SEC-1은 r에서 R의 빠른 계산을 허용하기위한 추가 정보를 추가 할 수 있습니다에서 읽은 내용에서

. 이것은 R 그 자체 일 수 있습니다. r = xR mod n으로 EccPoint에서 r을 계산할 수 있어야합니다.

검증을 가속화하기 위해이 메커니즘을 지원합니까? 아니면 OpenSSL에 r을 공급하기 위해 추가 정보를 제거해야합니까?

답변

0

섹션 4.2.5 - (extern '는 말 그대로 데이터에 표시되지 의미 임) http://www.etsi.org/deliver/etsi_ts/103000_103099/103097/01.02.01_60/ts_103097v010201p.pdf에서 4.2.8은 다음과 같은 구조를 제공합니다 :

enum { 
    x_coordinate_only(0), 
    compressed_lsb_y_0(2), 
    compressed_lsb_y_1(3), 
    uncompressed(4), 
    (2^8-1) 
} EccPointType; 

struct { 
extern PublicKeyAlgorithm algorithm; 
extern uint8 field_size; 
EccPointType type; 
opaque x[field_size]; 
select(type) { 
    case x_coordinate_only: 
    case compressed_lsb_y_0: 
    case compressed_lsb_y_1: 
     ; 
    case uncompressed: 
     opaque y[field_size]; 
    unknown: 
     opaque data<var>; 
    } 
} EccPoint; 

struct { 
    extern PublicKeyAlgorithm algorithm; 
    extern uint8 field_size; 
    EccPoint R; 
    opaque s[field_size]; 
} EcdsaSignature; 

struct { 
    PublicKeyAlgorithm algorithm; 
    select(algorithm) { 
     case ecdsa_nistp256_with_sha256: 
      EcdsaSignature ecdsa_signature; 
     unknown: 
      opaque signature<var>; 
    } 
} Signature; 

당신이 P-256에 ECDSA의 것을 알고, SHA256을 사용하고 "압축 된 y-1"포인트를 얻었습니다.먼저 우리가 알고있는 것을 사용하여 이러한 구조체의 '선택'부분을 모두 해결하고 '통근'모든 필드를 제거하자 : 좋아

struct { 
    PublicKeyAlgorithm algorithm; // 1 byte = 0x00 ("ecdsa, P-256, sha256") 
    {        //EcdsaSignature ecdsa_signature 
     {       //EccPoint R 
      EccPointType type;  //1 byte = 0x03 ("compressed lsb y-1") 
      opaque x[field_size];  //these are the first 32 opaque bytes 
      ;       // select(type) resolves to nothing. 
     } 
     opaque s[field_size];  //these are the second 32 opaque bytes 
    } 
} Signature; 

합니다. 그것은 더 간단합니다. 이제 모든 바이트가 무엇인지 알 수 있습니다. 그렇다면 "압축 포인트"에 대한이 모든 사업은 무엇입니까? 포인트 압축은 실제로 네트워크를 통해 전송해야하는 데이터의 양을 최소화하는 데 중점을 둡니다. NIST 곡선 위의 점의 X 좌표가 주어지면 Y 좌표를 풀 수 있지만 가능한 대답은 2 가지입니다. Certicom의 몇몇 영리한 사람들은 주어진 X 좌표와 함께 가능한 두 개의 Y 좌표가 항상 최하위 비트가 다른 것을 알아 차 렸습니다. 따라서 X를 모두 보내야 만하는 동안 Y (즉, 단지 충분한 정보이므로 Y에 대한 두 솔루션 중 어느 것이 맞는지 알 수 있습니다). EccPointType "compressed lsb y-1"은 X 좌표의 경우 올바른 Y 좌표가 LSb에 1을 갖는 좌표임을 나타냅니다.

가장 좋은 소식은 걱정할 필요가 없다는 것입니다. ECDSA는 'x'라고 표시된 첫 번째 불투명 한 얼룩에 앉아있는 R의 X 좌표 만 사용합니다.

그래서 이것은 당신이 아무것도 할 필요가 없습니다 "라고하는 장황한 설명했다. 이미 권리 r (= X의 R의 COORD)와 s OpenSSL을의 ECDSA_do_verify에 먹이를 보유하고 있습니다.