2011-10-15 5 views
0

Je souhaite créer une signature pour un fichier à l'aide d'OpenSSL. Je crois que mon résultat devrait correspondre à la testfile.sig générée par OpenSSL cette façon:Comment signer un fichier en utilisant libssl?

$ openssl dgst -sha1 -binary <testfile> testfile.sha1 
$ openssl rsautl -sign -in testfile.sha1 -inkey rsa_private.pem -keyform PEM -out testfile.sig 

$ openssl rsautl -verify -inkey rsa_public.pem -pubin -in testfile.sig -hexdump 
Loading 'screen' into random state - done 
0000 - 9f 23 88 15 2b af d6 a6-9f 4f 1f 7e ee b0 90 dd .#..+....O.~.... 
0010 - 69 99 2b 3d          i.+= 

Alors, je le code par qui a été posté café ici: How to read key file for use with HMAC_Init_ex() et vient d'ajouter un petit morceau pour sauver la données après EVP_SignFinal() dans un fichier, alors je pourrait simplement vérifier avec OpenSSL et la clé publique:

FILE * fp = fopen("out.sig", "wb"); 
if (fp) { 
    printf("Writing the signature in a file. # of bytes: %u.\n", sig_len); 
    fwrite(sig, 1, sig_len, fp); 
    fclose(fp); 
} 

et à ma grande surprise, je suis arrivé ceci:

$ openssl rsautl -verify -inkey rsa_public.pem -pubin -in out.sig -hexdump 
Loading 'screen' into random state - done 
0000 - 30 21 30 09 06 05 2b 0e-03 02 1a 05 00 04 14 9f 0!0...+......... 
0010 - 23 88 15 2b af d6 a6 9f-4f 1f 7e ee b0 90 dd 69 #..+....O.~....i 
0020 - 99 2b 3d           .+= 

Maintenant, si vous observez la sortie de la vérification de out.sig, vous verrez que les 20 derniers octets correspondent à la sortie de données de la vérification de testfile.sig. Et ces 20 octets sont en effet le hachage SHA-1 de mon fichier. Mais quels sont les 15 premiers octets au début? EVP_SignInit()/EVP_SignUpdate()/EVP_SignFinal() n'est-il pas censé mettre uniquement le hash dans le message, ou est-ce que quelque chose me manque?

Si vous avez besoin de plus d'informations, s'il vous plaît faites le moi savoir. Merci

pleine fonction qui était uset pour signer le fichier:

int do_evp_sign(FILE * rsa_pkey_file, FILE * in_file) 
{ 
    OpenSSL_add_all_digests(); 
    ERR_load_crypto_strings(); 

    EVP_PKEY * pkey = PEM_read_PrivateKey(rsa_pkey_file, NULL, NULL, NULL); 
    if (pkey == NULL) { 
     ERR_print_errors_fp(stderr); 
     return 1; 
    } 

    fseek(in_file, 0, SEEK_END); 
    const size_t lSize = ftell(in_file); 
    rewind(in_file); 

    EVP_MD_CTX md_ctx; 
    EVP_SignInit(&md_ctx, EVP_sha1()); 

    size_t len; 
    unsigned char buffer[4096]; 

    size_t bytesLeft = lSize; 
    while (bytesLeft > 0) { 
     const size_t count = (bytesLeft > sizeof(buffer) ? sizeof(buffer) : bytesLeft); 
     len = fread(buffer, 1, count, in_file); 
     if (len != count) { 
      fprintf(stderr, "Read error! len (%u) != count (%u).\n", len, count); 
      EVP_PKEY_free(pkey); 
      return 1; 
     } 
     if (!EVP_SignUpdate(&md_ctx, buffer, len)) 
     { 
      ERR_print_errors_fp(stderr); 
      EVP_PKEY_free(pkey); 
      return 1; 
     } 
     bytesLeft -= len; 
    } 

    unsigned int sig_len; 
    unsigned char * sig = (unsigned char *)malloc(EVP_PKEY_size(pkey)); 

    if (!sig) { 
     fprintf(stderr, "Couldn't allocate %u bytes of memory.\n", EVP_PKEY_size(pkey)); 
     EVP_PKEY_free(pkey); 
     return 1; 
    } 

    if (!EVP_SignFinal(&md_ctx, sig, &sig_len, pkey)) 
    { 
     ERR_print_errors_fp(stderr); 
     EVP_PKEY_free(pkey); 
     free(sig); 
     return 1; 
    } 

    FILE * fTemp = fopen("out.sig", "wb"); 
    if (fTemp) { 
     printf("Writing the signature to a file. Number of bytes: %u.\n", sig_len); 
     fwrite(sig, 1, sig_len, fTemp); 
     fclose(fTemp); 
    } 

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

    EVP_PKEY_free(pkey); 
    free(sig); 

    return 0; 
} 

Répondre

1

Qu'est-ce que vous avez il y a un encodage ASN.1 de la valeur de hachage.

0000 - 30 21 30 09 06 05 2b 0e-03 02 1a 05 00 04 14 9f 0!0...+......... 
0010 - 23 88 15 2b af d6 a6 9f-4f 1f 7e ee b0 90 dd 69 #..+....O.~....i 
0020 - 99 2b 3d           .+= 

30 - SEQUENCE 
21 - length (33 bytes) 
30 - SEQUENCE 
09 - length (9 bytes) 
    06 - OID 
    05 - length (5 bytes) 
    2b 0e 03 02 1a = 1 2 14 3 2 26 = SHA-1 
    05 - NULL 
    00 - length (0 bytes) 
04 - Octet String 
14 - length (20 bytes) 
    9f ... 3d - contents (the digest) 

Comment exactement avez-vous généré le résumé (en code)? Il semble que tout ce que vous avez utilisé l'ait converti en ASN.1 au lieu de le laisser "brut", et c'est ce que vous avez signé.

+0

Merci, maintenant c'est logique .. Je ne sais pas comment le laisser comme un hachage cru .. encore. J'ai mis à jour le poste avec la fonction. Comme vous pouvez le voir, je ne fais pas séparément le hachage, car c'est implicitement fait par les fonctions EVP_Sign *. Donc, si vous savez comment je peux changer cela, s'il vous plaît faites le moi savoir. – Amy

+0

Il semble que EVP_Sign suit EMSA-PKCS1-v1_5 (voir http://tools.ietf.org/html/rfc3447#section-9.2). Comme vous pouvez le voir, l'étape 2 est "encoder" ce qui produit la sortie que vous obtenez. Je ne suis pas sûr que ce soit un défaut ou un comportement fixe. Quand j'avais besoin d'utiliser d'autres choses, j'ai appelé RSA_private_encrypt directement. –

Questions connexes