2012-02-21 4 views
1

OpenSSL 문서 다음으로, 내가하고있는 일이 정확하다고 생각하지만 실제로는 그렇지 않습니다. 파일을 컴파일하면 (gcc -g -Wall -Wextra -lssl sign.c) 오류 또는 경고가 발생하지 않습니다. EVP_VerifyFinal()은 항상 0을 반환합니다 (검사에 실패했음을 의미). 그 원인은 무엇입니까?openssl이 서명을 정확히 확인하지 않음

static const EVP_MD * type; 

unsigned char * sha(char * input) 
{ 
    EVP_MD_CTX c; 
    unsigned char *md; 
    unsigned int md_len; 

    md = malloc(EVP_MAX_MD_SIZE); 

    EVP_MD_CTX_init(&c); 
    EVP_DigestInit_ex(&c, type, NULL); 
    EVP_DigestUpdate(&c, input, strlen(input)); 
    EVP_DigestFinal_ex(&c, md, &md_len); 
    EVP_MD_CTX_cleanup(&c); 

    return md; 
} 

unsigned char * sign(EVP_PKEY * key, unsigned char * data) 
{ 
    EVP_MD_CTX c; 
    unsigned char *sig; 
    unsigned int len; 

    EVP_MD_CTX_init(&c); 
    sig = malloc(EVP_PKEY_size(key)); 

    EVP_SignInit(&c, type); 
    EVP_SignUpdate(&c, data, strlen((char *)data)); 
    EVP_SignFinal(&c, sig, &len, key); 

    EVP_MD_CTX_cleanup(&c); 

    return sig; 
} 

int verify(EVP_PKEY * key, unsigned char * data, unsigned char * original) 
{ 
    EVP_MD_CTX c; 
    int ret; 

    EVP_MD_CTX_init(&c); 
    EVP_VerifyInit(&c, type); 
    EVP_VerifyUpdate(&c, data, (unsigned int)sizeof(data)); 
    ret = EVP_VerifyFinal(&c, original, (unsigned int)strlen((char *)original), key); 
    return ret; 
} 

int main(void) 
{ 
    EVP_PKEY *sk, *pk; 
    FILE *sfd, *pfd; 
    unsigned char *hash, *sig; 
    unsigned int i; 

    sfd = fopen("secret.pem", "r"); 
    pfd = fopen("public.pem", "r"); 
    sk = PEM_read_PrivateKey(sfd, NULL, NULL, NULL); 
    pk = PEM_read_PUBKEY(pfd, NULL, NULL, NULL); 
    fclose(sfd); 
    fclose(pfd); 

    OpenSSL_add_all_digests(); 
    type = EVP_get_digestbyname("SHA1"); 

    hash = sha("moo"); 

    for(i = 0; i < sizeof(hash); i++) 
     printf("%02x", hash[i]); 
    printf("\n"); 

    sig = sign(sk, hash); 
    switch(verify(pk, sig, hash)) 
    { 
     case 0: 
      printf("Check failed.\n"); 
      break; 
     case 1: 
      printf("Check succeeded!\n"); 
      break; 
     default: 
      printf("Oh look, an error: %d", ERR_get_error()); 
      break; 
    } 

    return 0; 
} 

답변

0

올바른 크기를 전달되지 않습니다 data 이후

EVP_VerifyUpdate(&c, data, (unsigned int)sizeof(data)); 

sizeof(data) 아마 4 또는 8 (포인터를 유지하는 데 필요한 바이트 수)이며, unsigned char *으로 정의된다.

할당 한 실제 바이트 수 (예 : EVP_PKEY_size(key))를 전달해보십시오. 당신은 verify() 함수에 그것을 전달해야 할 것입니다.

다른 것이 잘못되었을 수도 있지만이 사람이 내 눈을 사로 잡았습니다.

0

나는 이것이 오래된 질문이지만, 하나의 버그로 인해 사용자를 혼란스럽게 할 수 있습니다.

verify 함수에서 원본과 데이터는 EVP_VerifyUpdate 이전의 원본과 EVP_VerifyFinal의 데이터로 스왑되어야합니다. 바이트 배열은 "\ 0"으로 인식 될 유효한 값으로 0x00을 포함 할 수 있으므로 문자열 길이를 사용하지 않아야합니다.

관련 문제