2013-05-17 2 views
3

ECDSA로 수행하려는 작업은 외부 ECDSA 하드웨어 (실제 공개 키)에서 가져온 값에서 x "압축 된"좌표와 ay "비트" OpenSSL 함수 호출로 y 좌표 (압축되지 않은)를 복구하려고합니다.ECDSA : openssl을 사용하여 x 압축을 풀 때 y 좌표를 얻는 방법

다음 코드를 시도하지만 예상대로 작동하지 않습니다. 내 xy [] 배열에 올바른 데이터가 채워지지 않습니다. 누구든지 도와 줄 수 있습니까?

나는 ECDSA에 새로운에는 OpenSSL 심지어 새로운 해요,하지만 난 다음 할 수있는 생각 : 당신은 bn_compressed 통과해야

BN_bin2bn(&x_compressed_byte_array[0],200,NULL); // length is in bits? 

코드이 줄을

enter code here 


EC_GROUP *curve_group = EC_GROUP_new_by_curve_name(NID_X9_62_prime192v1); 
EC_POINT *point; 
BIGNUM *x_compressed = BN_new(); 
int y_chooser_bit = 1; 
int results = 0; 
size_t returnsize = 0; 

unsigned char x_compressed_byte_array[25] = {0x02, 0x71, 0xc0, 0x73, 0x73, 
              0x9b, 0xbf, 0xc2, 0x0a, 
              0x81, 0xcd, 0xdd, 0xf4, 
              0xcf, 0xca, 0xc7, 0xb5, 
              0xa9, 0x99, 0x61, 0x23, 
              0x2c, 0x5c, 0x63, 0x7a}; 

unsigned char xy[49]; 

// create a big number from the unsigned char array 
BN_bin2bn(&x_compressed_byte_array[0],200,NULL); // length is in bits? 

point = EC_POINT_new(curve_group); 

results = EC_POINT_set_compressed_coordinates_GFp(curve_group, point, 
                x_compressed,                
                y_chooser_bit, NULL); 

returnsize = EC_POINT_point2oct(curve_group, point, 
           POINT_CONVERSION_UNCOMPRESSED, 
           &xy[0], 49, NULL); // 49 

// clean up allocated memory 
BN_free(x_compressed); 
EC_POINT_free(point); 
EC_GROUP_free(curve_group); 

답변

2

을 , 변환 된 결과를 보유하기 위해 생성 한 BIGNUM. 길이는 바이트 단위입니다.

BN_bin2bn(&x_compressed_byte_array[0],sizeof(x_compressed_byte_array),x_compressed); 

set_compressed_coordinates를 실행 한 후 방금 만든 포인트가 그룹에서 올바르게 찾았는지 확인할 수 있습니다.

if (!EC_POINT_is_on_curve(curve_group,point,NULL)) return 0; 

포인트 좌표 (x, y)를 자세히 검사하려면 코드에이 코드를 삽입하십시오.

if (!EC_POINT_get_affine_coordinates_GFp(curve_group, point, x, y, NULL)) return 0; 
fprintf(stdout, "\point = (x,y)\n"); 
fprintf(stdout, "  x = 0x"); 
BN_print_fp(stdout, x); 
fprintf(stdout, "\n  y = 0x"); 
BN_print_fp(stdout, y); 
fprintf(stdout, "\n"); 

새/무료 BIGNUM x 및 y는 기능의 첫 번째/마지막에 기억하십시오.

BIGNUM *x, *y; 
x = BN_new(); 
y = BN_new(); 

/* your code */ 

if(x) BN_free(x); 
if(y) BN_free(y); 

그리고 제대로 작동합니다. 결과의 XY [49] 내가 가지고는

0x0471C073739BBFC20A81CDDDF4CFCAC7B7A99961232C5C637C388AB06AA7E43A2B5CFE2D7F3AC2DF910D6F8D8F209CD817

+0

당신에게 너무 많은 ChiaraHsieh 감사합니다! 나는 당신의 대답을 반복 할 수있었습니다 (xy [49]). 자, 내 유일한 혼란은 압축 된 x 키를 처리하는 가장 좋은 방법입니다. 위의 코드는 192 비트 곡선의 압축 키에 25 바이트를 사용하지만 24 바이트를 사용해야하고 "y_bit"을 전달하는 데 의존해야합니다. 그래서, 내 질문은 짐작 : OPENSSL 압축 된 키의 여분의 바이트 필요합니까 또는 24 비트 x 좌표를 y- 비트 사용해야합니까? 고맙다! – user2395290

+1

반갑습니다. :) 당신은 25 바이트가 필요합니다. 첫 번째 바이트는 x 좌표가 압축되지 않았거나 하이브리드 또는 압축 된 형식임을 나타냅니다. 예를 들어, x '0x02'의 첫 번째 바이트는 x가 압축 된 형식임을 나타냅니다. xy'0x04'의 첫 번째 바이트는 xy가 압축되지 않은 형식임을 나타냅니다. OPENSSL은 ec_point (x, y)를 올바르게 복구하기 위해이 표시기와 물론 ybit를 함께 사용해야합니다. 포인트 압축은 참조가 필요한 경우 X9.62 표준에서 정의됩니다. – ChiaraHsieh