2010-01-12 5 views
2

openssl을 사용하여 RSA 개인 키를 생성했습니다.HMAC_Init_ex()와 함께 사용할 키 파일을 읽는 방법

OpenSSL 라이브러리의 HMAC _ *() 함수를 일반 C로 사용하여 데이터를 해시/서명해야하지만이 파일에서 개인 키 데이터를 올바르게 추출하는 방법은 확실하지 않습니다.

내가 아는 바로는, 그 파일은 B64로 인코딩되었으므로 버퍼를 코드화 해제하고 버퍼에 저장했습니다. 그러나 HMAC _ *() 함수는 해싱과 서명이 결과가 예상 한 것이 아니기 때문에 실제 키를 사용하지 않는 것으로 보입니다.

헤더를 버리겠습니까? 또는 사용자가 직접 키를 읽는 대신 키를 읽는 기능이 있습니까?

내가 PEM_read_PrivateKey()를 통해 왔지만 HMAC *() 함수로 직접 사용할 수없는 EVP_PKEY 구조체를 만듭니다.

힌트가 있습니까? 감사합니다.

답변

4

HMAC를 오해 한 것입니다. HMAC는 공유 (대칭) 키를 사용하여 키순 해시 데이터를 만듭니다. 생성 된 키를 확인하기 위해 동일한 키가 필요합니다 (은 아니요 서명입니다). 키는 특정 구조가없는 임의의 비트 시퀀스입니다.

RSA 서명은 암호화되지 않은 정상적인 해시를 기반으로합니다. RSA 서명을 만들려면 EVP_SignInit()/EVP_SignUpdate()/EVP_SignFinal() 함수를 사용해야합니다. 예를 들어, RSA-와-SHA256 서명을위한 EVP 컨텍스트를 intialise하기 위해, 당신은 할 것 :의 OpenSSL 버전이 SHA256을 포함하지 않는 경우

EVP_MD_CTX ctx; 
EVP_MD_CTX_init(&ctx); 
EVP_SignInit(&ctx, EVP_sha256()); 

(당신은 RSA-와-SHA1에 대한 EVP_sha1()을 사용할 수 있습니다 서명).

당신이 당신의 RSA 키에서 그것을 초기화됩니다의 EVP_PKEY * EVP_SignFinal() 필요한 얻으려면 :

EVP_PKEY *pkey = EVP_PKEY_new(); 
EVP_PKEY_set1_RSA(pkey, rsakey); 

openssl 명령 행 유틸리티에 의해 생성 된 base64 인코딩 RSA 키가 그래서 그냥 할 수있는, PEM 형식으로되어 있습니다 PEM_read_RSAPrivateKey()을 사용하여 파일에서 직접 RSA * 핸들로 읽으십시오.

#include <stdio.h> 
#include <stdlib.h> 
#include <openssl/evp.h> 
#include <openssl/pem.h> 
#include <openssl/rsa.h> 

int do_evp_sign(FILE *rsa_pkey_file, FILE *in_file) 
{ 
    RSA *rsa_pkey = NULL; 
    EVP_PKEY *pkey = EVP_PKEY_new(); 
    EVP_MD_CTX ctx; 
    unsigned char buffer[4096]; 
    size_t len; 
    unsigned char *sig; 
    unsigned int siglen; 
    int i; 

    if (!PEM_read_RSAPrivateKey(rsa_pkey_file, &rsa_pkey, NULL, NULL)) 
    { 
     fprintf(stderr, "Error loading RSA Private Key File.\n"); 
     return 2; 
    } 

    if (!EVP_PKEY_assign_RSA(pkey, rsa_pkey)) 
    { 
     fprintf(stderr, "EVP_PKEY_assign_RSA: failed.\n"); 
     return 3; 
    } 

    EVP_MD_CTX_init(&ctx); 

    if (!EVP_SignInit(&ctx, EVP_sha1())) 
    { 
     fprintf(stderr, "EVP_SignInit: failed.\n"); 
     EVP_PKEY_free(pkey); 
     return 3; 
    } 

    while ((len = fread(buffer, 1, sizeof buffer, in_file)) > 0) 
    { 
     if (!EVP_SignUpdate(&ctx, buffer, len)) 
     { 
      fprintf(stderr, "EVP_SignUpdate: failed.\n"); 
      EVP_PKEY_free(pkey); 
      return 3; 
     } 
    } 

    if (ferror(in_file)) 
    { 
     perror("input file"); 
     EVP_PKEY_free(pkey); 
     return 4; 
    } 

    sig = malloc(EVP_PKEY_size(pkey)); 
    if (!EVP_SignFinal(&ctx, sig, &siglen, pkey)) 
    { 
     fprintf(stderr, "EVP_SignFinal: failed.\n"); 
     free(sig); 
     EVP_PKEY_free(pkey); 
     return 3; 
    } 

    printf("Signature: \n"); 
    for (i = 0; i < siglen; i++) 
    { 
     printf("%02x", sig[i]); 
     if (i % 16 == 15) 
      printf("\n"); 
    } 
    printf("\n"); 

    free(sig); 
    EVP_PKEY_free(pkey); 
    return 0; 
} 
: 여기

은 RSA 개인 키 파일을 읽고 다른 파일의 서명을 생성하는 데 사용의 예