2012-02-21 13 views
4

次の文を使用してRSA公開鍵と秘密鍵を作成しています。Cルーチンとopenssl dgst、rsautlコマンドを使用したときの署名が異なります

opensslのgenrsa -out ksign_private.pem 1024 opensslのRSA -in ksign_private.pem -pubout> ksign_public.pem

それから私はopensslのlibcryptoなどから、PEM_read_RSAPrivateKey、EVP_PKEY_assign_RSA、EVP_SignInit、EVP_SignUpdate、EVP_SignFinal機能を使用するプログラムを持っています署名ファイルを生成する。

また、PEM_read_RSA_PUBKEY、EVP_PKEY_assign_RSA、EVP_VerifyInit、EVP_VerifyUpdate、EVP_VerifyFinalを使用して署名が検証できることを確認するルーチンもあります。 これらのルーチンのソースコードは以下に添付されています。

これらの機能を使用する場合、SHA1署名を作成し、秘密鍵で暗号化し、公開鍵を使用して復号化することができます。

しかし、openssl rsautlを使って同じデータファイル、同じプライベート公開鍵、およびopenssl rsautlによって作成されているシグネチャを使用しようとしましたが、大きく異なります。

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

openssl rsautlまたはdgstコマンドを使用するときに私が間違って使用しているオプションはありますか?

#include <stdio.h> 
#include <unistd.h> 
#include <stdlib.h> 
#include <ctype.h> 
#include <unistd.h> 
#include <string.h> 
#include <openssl/sha.h> 
#include <errno.h> 
#include <getopt.h> 
#include <sys/types.h> 
#include <sys/stat.h> 
#include <openssl/evp.h> 
#include <openssl/pem.h> 
#include <openssl/rsa.h> 

int ksignEvpSign(FILE * private_key, FILE * inFileFP, FILE * outFileFP); 
int ksignEvpVerify(FILE * public_key, FILE * dataFileFP, FILE * signFileFP); 

int ksignEvpSign(FILE * privateKeyFP, FILE * inFileFP, FILE * outFileFP) 
{ 
    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; 

    if (!PEM_read_RSAPrivateKey(privateKeyFP, &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, inFileFP)) > 0) { 
     if (!EVP_SignUpdate(&ctx, buffer, len)) { 
      fprintf(stderr, "EVP_SignUpdate: failed.\n"); 
      EVP_PKEY_free(pkey); 
      return 3; 
     } 
    } 

    if (ferror(inFileFP)) { 
     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; 
    } 
    fwrite(sig, siglen, 1, outFileFP); 
    free(sig); 
    EVP_PKEY_free(pkey); 
    return 0; 
} 

int ksignEvpVerify(FILE * publicKeyFP, FILE * dataFileFP, FILE * sigFileFP) 
{ 
    RSA *rsa_pkey = NULL; 
    EVP_PKEY *pkey; 
    EVP_MD_CTX ctx; 
    unsigned char buffer[4096]; 
    size_t len; 
    unsigned char *sig; 
    unsigned int siglen; 
    struct stat stat_buf; 

    if (!PEM_read_RSA_PUBKEY(publicKeyFP, &rsa_pkey, NULL, NULL)) { 
     fprintf(stderr, "Error loading RSA public Key File.\n"); 
     return 2; 
    } 
    pkey = EVP_PKEY_new(); 

    if (!EVP_PKEY_assign_RSA(pkey, rsa_pkey)) { 
     fprintf(stderr, "EVP_PKEY_assign_RSA: failed.\n"); 
     return 3; 
    } 
    /* Read the signature */ 
    if (fstat(fileno(sigFileFP), &stat_buf) == -1) { 
     fprintf(stderr, "Unable to read signature \n"); 
     return 4; 
    } 
    siglen = stat_buf.st_size; 
    sig = (unsigned char *)malloc(siglen); 
    if (sig == NULL) { 
     fprintf(stderr, "Unable to allocated %d bytes for signature\n", 
      siglen); 
     return 5; 
    } 
    if ((fread(sig, 1, siglen, sigFileFP)) != siglen) { 
     fprintf(stderr, "Unable to read %d bytes for signature\n", 
      siglen); 
     return 6; 
    } 
/* 
    printf("Signature:"); 
    for (i = 0; i < siglen; i++) { 
     fprintf(stdout, "%02x", sig[i]); 
     if (i % 16 == 15) 
      fprintf(stdout, "\n"); 
    } 
    fprintf(stdout, "\n"); 
*/ 

    EVP_MD_CTX_init(&ctx); 

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

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

    if (ferror(dataFileFP)) { 
     perror("input file"); 
     EVP_PKEY_free(pkey); 
     return 9; 
    } 

    if (!EVP_VerifyFinal(&ctx, sig, siglen, pkey)) { 
     fprintf(stderr, "EVP_VerifyFinal: failed.\n"); 
     free(sig); 
     EVP_PKEY_free(pkey); 
     return 10; 
    } 
    free(sig); 
    EVP_PKEY_free(pkey); 
    return 0; 
} 

答えて

4

pkeyutlコマンドは、任意のアルゴリズムを処理することができるpkeyutlためrsautlに好適でなければなりません。コマンドラインで同じシグネチャを取得するには、以下を使用する必要があります。

openssl pkeyutl -sign -in testfile.sha1 -inkey ksign_private.pem -pkeyopt digest:sha1 -outfile testfile.sig 

重要な部分は、あなたがダイジェスト値を使用しているopensslを語っています。それ以外の場合は、ダイジェストのダイジェストに署名しているようです。あなたが直接ハッシュにdgstコマンドを使用してのようなデータに署名することができ

+0

rsautlのソースは廃止されましたか?グーグルではこのページに戻ってきます。 – cgmb

+0

@cgmb:ありがとう、貧しい言葉の選択。私は説明段落の2行目から非推奨の印象を受けていると思う:https://www.openssl.org/docs/manmaster/apps/rsa.htmlと組み合わせた 'pkyutl'はより普遍的な/より好ましい。 – Greyson

3

openssl dgst -sha1 -binary -sign privkey.pem <myData> mySignature

は、すべてのオプションのためのdocsを参照してください。

関連する問題