4

OppenSSL EC関数 EC_KEY_generate_key を使用して公開/秘密鍵ペアを生成した後、それらを別々のファイルに保存し、それらを取得してECDH KEYを生成するプログラムを作成しようとしています。

私の問題は、それらを正しく (追加の文字なしで) 保存したにもかかわらず、ファイルを読み取って 16 進文字を BIGNUM に変換しようとすると、文字 '04' または '00' がランダムに表示される (場合によっては表示されない) ことです。そのため、公開鍵/秘密鍵を設定して鍵全体をチェックしようとすると失敗します。誰かがこの問題について私を助けてくれますか? これらの文字が原因でキー チェックの失敗が発生した可能性がありますか、それとも正常ですか?

秘密鍵を生成/保存するコードは次のとおりです(公開鍵は同じです):

    EC_KEY *b = NULL;
const BIGNUM *ppriv_b;
FILE *claveprivb;
const EC_GROUP *group;

b = EC_KEY_new_by_curve_name(NID_X9_62_prime192v1);
group = EC_KEY_get0_group(b);

EC_KEY_generate_key(b);
    claveprivb = fopen("/tmp/mnt/claveprivb", "w+");
    ppriv_b = EC_KEY_get0_private_key(b);
if ((ppriv_b != NULL)) 
    BN_print_fp(claveprivb,ppriv_b);
    fclose(claveprivb);

    //Afterwards do the same with the public key

そして、秘密鍵を取得するための私のコードは次のとおりです。

    int i, s, blen, bout, ret = 0;
unsigned char *bbuf;
FILE *clavepriv, *clavetotalb;
const char cpriv_string[PRIVATE_KEY_SIZE];
BIGNUM *priv;
EC_KEY *b = NULL;
const EC_GROUP *groupb;

    b = EC_KEY_new_by_curve_name(NID_X9_62_prime192v1);
groupb = EC_KEY_get0_group(b);
    //Open the file with the hexadecimals (PRIVATE KEY)
    clavepriv = fopen("/tmp/mnt/claveprivb", "r");
kk2 = fread(&cpriv_string, sizeof(char), PRIVATE_KEY_SIZE, clavepriv);

priv = BN_new();
    //THIS FUNCTION (HEX2BN) GENERATES THE RANDOM CHARACTER: 
kk2 = BN_hex2bn(&priv, cpriv_string);
ret = EC_KEY_set_private_key(b, priv);

    //HERE I retrieve the public key by the same way and set it into EC_KEY b,
    //the same random character appears in the public key

    if (!EC_KEY_check_key(b)) {
    printf("EC_KEY_check_key failed\n");
} else {
    printf("Key verified OK\n");
}
    //It fails when try to check it.

int k;
clavetotalb = fopen("/tmp/mnt/clavetotalb", "w+");
k = EC_KEY_print_fp(clavetotalb, b, 0);

bout = ECDH_compute_key(bbuf, blen, EC_KEY_get0_public_key(b), b,
        KDF1_SHA1);

どんなアドバイスでも大歓迎です!!!!ありがとう!!!

回答の投稿を読んだ後、これらの方法を使用して公開鍵をデコードおよびエンコードしようとしましたが、ECDH キーを計算しようとすると、セグメンテーション違反が発生します。私のプログラムの目標は、2 つの EC キーを生成し、それらをいくつかのファイルに書き込んでから、それらを取得して ECDH キーを計算することです。これは、最初のスレッドで元のプログラムから変更したもののリストです。何か問題がある場合は教えてください。

* Generate EC key (public & private)
* Decode the private key with i2d_ECPrivatekey()
* Decode the public key with i2o_ECPublickey()
* Write them into several files.
* Read the file with the public key.
* Encode it with o2i_ECPublickey()
* Read the file with the private key.
* Encode it with d2i_ECPrivatekey().
* Compute the ECDH key.(Here is where I get the segmentation fault)

私はこの OpenSSL ライブラリにかなりうんざりしています... 初めてのユーザーにはとてもアクセスできません...

4

1 に答える 1

5

EC公開鍵は整数ではありません。これは、整数のペアと見なすことができる曲線ポイントです。これらの2つの整数は、点の座標(XおよびYと呼ばれることが多い)です。

いくつかの表記法:曲線は有限体で定義されています。有限体要素は、 0からq-1までの整数にマッピングできます。ここで、qは体のサイズです(使用する曲線の場合、qは2 192よりわずかに小さい整数です)。nをq -1のバイト単位のサイズとします。これは、 q -1の符号なしビッグエンディアン表現のサイズ、つまり2 8(n-1) <= q-1< 28nのような整数です。曲線の場合、n=24です。

これらの表記法では、曲線ポイントの標準表現は正確に1 + 2nバイトで構成され、この順序で次のようになります。

  • 値0x04のバイト
  • nバイトを超えるxの符号なしビッグエンディアン表現
  • nバイトを超えるyの符号なしビッグエンディアン表現

したがって、これは「0x04」の余分なバイトを説明します。また、xyは正確にnバイトでエンコードされるため、実際の値が2 8(n-1)より小さいことが判明した場合、これにより余分な「0x00」バイトが強制的に含まれる可能性があります(曲線では、平均して、公開鍵の約1/128に当てはまるはずです)。

この表現には他にもバリエーションがあります(圧縮され、合計サイズが1 + nで最初のバイトが0x02または0x03であり、ハイブリッドでサイズが1 + 2nで、最初のバイトが0x06または0x07です)。 ECDSA標準(X9.62-2005)ではオプションと見なされており、圧縮形式は特許を取得しているという噂があります。

結論:EC公開鍵をエンコードおよびデコードする場合は、およびを調べてo2i_ECPublicKey()i2o_ECPublicKey()エンコードされた整数ではなく、任意のバイトのシーケンスとして処理する必要があります。

于 2011-05-06T12:36:08.713 に答える