2017-02-06 24 views
0

これはopenssl rsa 4096ビット鍵を生成するために書いたc関数です。上記の関数によって生成された関数が適切なopenssl rsaキーを生成していない

bool rsa_gen_keys() 
    {  
    int    ret = 0; 
    RSA    *rsa = NULL; 
    BIGNUM   *bignum = NULL; 
    BIO    *bio_private = NULL; 
    BIO    *bio_public = NULL; 
    int    bits = 4096; 

    unsigned long k = RSA_F4; 

    bignum = BN_new(); 
    ret = BN_set_word(bignum,k); 
    if(ret != 1){ 
     goto cleanup; 
    } 

    rsa = RSA_new(); 
    ret = RSA_generate_key_ex(rsa, bits, bignum, NULL); 
    if(ret != 1){ 
     goto cleanup; 
    } 
    // write rsa private key to file 
    bio_private = BIO_new_file("private_new.pem", "w+"); 
    ret = PEM_write_bio_RSAPrivateKey(bio_private, rsa, NULL, NULL, 0, NULL, NULL); 
    BIO_flush(bio_private); 
    // write rsa public key to file 
    bio_public = BIO_new_file("public_new.pem", "w+"); 
    ret = PEM_write_bio_RSAPublicKey(bio_public, rsa); 
    if(ret != 1){ 
     goto cleanup; 
    }  
    BIO_flush(bio_public); 
cleanup: 
    BIO_free_all(bio_private); 
    BIO_free_all(bio_public); 
    RSA_free(rsa); 
    BN_free(bignum); 
    return ret; 
} 

鍵は何かが欠けているように見えます。私は、キーファイルを生成するためにopensslコマンドを使用している場合、ファイルは正常に動作、しかし

140286309791384:error:0906D06C:PEM routines:PEM_read_bio:no start line:pem_lib.c:701:Expecting: PUBLIC KEY 

:私は別のプログラムでpublic_new.pemファイルを使用しようとすると、私は次のエラーを取得します。

$openssl genpkey -algorithm RSA -out private_key.pem -pkeyopt rsa_keygen_bits:4096 

私は、関数とコマンドラインから生成されたキーサイズが一致しないことに気付きました。これは手掛かりですが、これを修正するために私の機能を変更する必要がありますか?

-rw-rw-r-- 1 3272 Feb 6 09:19 private_key.pem 
-rw-rw-r-- 1 800 Feb 6 09:20 public_key.pem 
-rw-rw-r-- 1 3243 Feb 6 10:43 private_new.pem 
-rw-rw-r-- 1 775 Feb 6 10:43 public_new.pem 

はBTW、私は、2048ビットのキーを使用して上記を試して、私は同じ結果を得ると同じサイズの不一致

+1

'c/C++ function' ==未定義の動作です。 :P –

+0

どのようなフォームまたはエンコーディングが必要ですか?さまざまなエンコーディングを[OpenSSL RSAキーと.Net](http://stackoverflow.com/q/30475758/608639)で見ることができます。 – jww

答えて

2

openssl genpkey代わりPEM_write_bio_RSAPrivateKey(PKCS#1)のPEM_write_bio_PrivateKey(PKCS#8)を使用している:https://github.com/openssl/openssl/blob/master/apps/genpkey.c#L161-L164

public_key.pemの生成方法は表示されていませんが、PEM_write_bio_PUBKEY(X.509 SubjectPublicKeyInfo)とPEM_write_bio_RSAPublicKey(PKCS#1)で書かれている可能性があります。 PEMの鎧の観点から

  • PKCS#1公開:RSA公開鍵
  • X.509 SubjectPublicKeyInfoでのBEGIN:PUBLIC KEYをBEGIN
  • PKCS#1プライベート:BEGIN RSA PRIVATE KEY
  • PKCS#8:プライベートキー
+0

その違いを説明します。 EVP呼び出しを使用して、EVP_PKEY_keygen()のように直接RSA呼び出しではなく正しい形式を生成する必要があるかもしれません。 – seedhom

+1

'EVP_ *'(エンベロープ(d))構造体と関連するファイル形式は、「これはどのような種類の鍵か」と「ああ、ここに鍵です。 'RSA'直接APIを使うということは、それがどのキータイプであるかを既に知っていることを意味します。 – bartonjs

0

私はPKCS#8とX.509のキーのフォーマットを使用する必要があることを認識しました。そこで私はそれらを生成するためにEVP関数に切り替えました。ここで私が使用したコードの非常に単純化されたバージョンです(エラーチェックなし):

bool rsa_gen_keys() { 
    int ret = 0; 
    BIO *bio_private = NULL; 
    BIO *bio_public = NULL; 
    int bits = 4096; 

    EVP_PKEY_CTX *ctx; 
    EVP_PKEY *pkey = NULL; 

    // Get the context 
    ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL); 
    if (!ctx) 
     goto cleanup; 

    // init keygen 
    if (EVP_PKEY_keygen_init(ctx) <= 0) 
     goto cleanup; 

    // set the bit size 
    if (EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, bits) <= 0) 
    goto cleanup; 

    /* Generate key */ 
    if (EVP_PKEY_keygen(ctx, &pkey) <= 0) 
     goto cleanup; 


    // write rsa private key to file 
    bio_private = BIO_new_file("private_new.pem", "w+"); 
    ret = PEM_write_bio_PrivateKey(bio_private, pkey, NULL, NULL, 0, NULL, NULL); 
    if (ret != 1) { 
     goto cleanup; 
    } 
    BIO_flush(bio_private); 

    // write rsa public key to file 
    bio_public = BIO_new_file("public_new.pem", "w+"); 

    //ret = PEM_write_bio_RSAPublicKey(bio_public, rsa); 
    ret = PEM_write_bio_PUBKEY(bio_public, pkey); 
    if (ret != 1) { 
     goto cleanup; 
    } 
    BIO_flush(bio_public); 


cleanup: 
    if(bio_private) BIO_free_all(bio_private); 
    if(bio_public) BIO_free_all(bio_public); 
    if(pkey) EVP_PKEY_free(pkey); 

    return ret; 
} 
関連する問題