5

openssl s_server/s_client の組み合わせを使用すると、キーペアを生成する特定の曲線が機能しないようです。次の方法を使用してこれを確認しました。

  • openssl ecparam -out ec_$curve.key -name $curve -genkeyforeach$curveで楕円曲線キーペアを作成するopenssl ecparam -list_curves

  • それぞれの自己署名証明書を生成しec_$curve.keyますopenssl req -x509 -new -days 365 -key ec_$curve.key -out ec_$curve.crt -subj $SOME_SUBJ

  • ごとec_$curve.keyに、次のことを行います: 1 つのウィンドウで、openssl s_server -cert ec_$curve.crt -key ec_$curve.key -accept 10000、別のウィンドウでopenssl s_client -host localhost -port 10000

私は握手をします:

Using default temp DH parameters Using default temp ECDH parameters ACCEPT ERROR 8606155664:error:1408A0C1:SSL routines:SSL3_GET_CLIENT_HELLO:no shared cipher:s3_srvr.c:1355: shutting down SSL CONNECTION CLOSED

次の曲線で作成されたキーペアのみc2.*:曲線 (例: c2pnb163v1)、prime192v[23]prime239.*およびsec.1[123].*曲線。他のすべての曲線は正常に機能します。

これは私には意味がありません。s_client は s_server と通信できる必要があるため、これは OpenSSL のバグであるか、クライアントまたはサーバー、あるいはその両方を間違って構成したかのいずれかです。サーバー側で -named_curve パラメーターを追加しようとしましたが、改善されません。OpenSSL のバージョンは 1.0.1e です。

それで、暗号/ECの手がかりをもっと持っている人、一体何がここで起こっているのですか?

4

3 に答える 3

2

RFC 4492 のセクション 5.1.1 によると、任意のパラメーターを持つ曲線もサポートされています (以下の任意の_明示_プライム_曲線を参照してください)。これは、テストする各曲線の定義とすべての EC パラメーターが見つかった場合、EC_GROUP_new_curve、EC_KEY_set_group、EC_KEY_get0_private_key などの openssl 呼び出しを介してキーを生成し、TLS ハンドシェイクで使用できることを意味します。

したがって、結論は、名前付き曲線を使用する代わりにカスタム曲線を使用する場合、生成しているすべてのキーをサポート できるということです。

 enum {
        sect163k1 (1), sect163r1 (2), sect163r2 (3),
        sect193r1 (4), sect193r2 (5), sect233k1 (6),
        sect233r1 (7), sect239k1 (8), sect283k1 (9),
        sect283r1 (10), sect409k1 (11), sect409r1 (12),
        sect571k1 (13), sect571r1 (14), secp160k1 (15),
        secp160r1 (16), secp160r2 (17), secp192k1 (18),
        secp192r1 (19), secp224k1 (20), secp224r1 (21),
        secp256k1 (22), secp256r1 (23), secp384r1 (24),
        secp521r1 (25),
        reserved (0xFE00..0xFEFF),
        arbitrary_explicit_prime_curves(0xFF01),
        arbitrary_explicit_char2_curves(0xFF02),
        (0xFFFF)
    } NamedCurve;

「openssl ecparam」には、名前付き曲線の ​​C コードを生成できる -C オプションもあります。

openssl ecparam  -name prime256v1  -C

名前付き曲線のパラメーターと一致するパラメーターを持つカスタム曲線のキーを生成するために使用できる EC_GROUP オブジェクトを作成するためのコードを生成します。

static unsigned char ec_p_256[] = {
    0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,
    0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF
    };

static unsigned char ec_a_256[] = {
    0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,
    0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFC
    };

static unsigned char ec_b_256[] = {
    0x5A,0xC6,0x35,0xD8,0xAA,0x3A,0x93,0xE7,0xB3,0xEB,0xBD,0x55,
    0x76,0x98,0x86,0xBC,0x65,0x1D,0x06,0xB0,0xCC,0x53,0xB0,0xF6,
    0x3B,0xCE,0x3C,0x3E,0x27,0xD2,0x60,0x4B
    };

static unsigned char ec_gen_256[] = {
    0x04,0x6B,0x17,0xD1,0xF2,0xE1,0x2C,0x42,0x47,0xF8,0xBC,0xE6,
    0xE5,0x63,0xA4,0x40,0xF2,0x77,0x03,0x7D,0x81,0x2D,0xEB,0x33,
    0xA0,0xF4,0xA1,0x39,0x45,0xD8,0x98,0xC2,0x96,0x4F,0xE3,0x42,
    0xE2,0xFE,0x1A,0x7F,0x9B,0x8E,0xE7,0xEB,0x4A,0x7C,0x0F,0x9E,
    0x16,0x2B,0xCE,0x33,0x57,0x6B,0x31,0x5E,0xCE,0xCB,0xB6,0x40,
    0x68,0x37,0xBF,0x51,0xF5
    };

static unsigned char ec_order_256[] = {
    0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,
    0xFF,0xFF,0xFF,0xFF,0xBC,0xE6,0xFA,0xAD,0xA7,0x17,0x9E,0x84,
    0xF3,0xB9,0xCA,0xC2,0xFC,0x63,0x25,0x51
    };

static unsigned char ec_cofactor_256[] = {
    0x01
    };



EC_GROUP *get_ec_group_256(void)
    {
    int ok=0;
    EC_GROUP *group = NULL;
    EC_POINT *point = NULL;
    BIGNUM   *tmp_1 = NULL, *tmp_2 = NULL, *tmp_3 = NULL;

    if ((tmp_1 = BN_bin2bn(ec_p_256, sizeof(ec_p_256), NULL)) == NULL)
        goto err;
    if ((tmp_2 = BN_bin2bn(ec_a_256, sizeof(ec_a_256), NULL)) == NULL)
        goto err;
    if ((tmp_3 = BN_bin2bn(ec_b_256, sizeof(ec_b_256), NULL)) == NULL)
        goto err;
    if ((group = EC_GROUP_new_curve_GFp(tmp_1, tmp_2, tmp_3, NULL)) == NULL)
        goto err;

    /* build generator */
    if ((tmp_1 = BN_bin2bn(ec_gen_256, sizeof(ec_gen_256), tmp_1)) == NULL)
        goto err;
    point = EC_POINT_bn2point(group, tmp_1, NULL, NULL);
    if (point == NULL)
        goto err;
    if ((tmp_2 = BN_bin2bn(ec_order_256, sizeof(ec_order_256), tmp_2)) == NULL)
        goto err;
    if ((tmp_3 = BN_bin2bn(ec_cofactor_256, sizeof(ec_cofactor_256), tmp_3)) == NULL)
        goto err;
    if (!EC_GROUP_set_generator(group, point, tmp_2, tmp_3))
        goto err;

    ok=1;
err:
    if (tmp_1)
        BN_free(tmp_1);
    if (tmp_2)
        BN_free(tmp_2);
    if (tmp_3)
        BN_free(tmp_3);
    if (point)
        EC_POINT_free(point);
    if (!ok)
        {
        EC_GROUP_free(group);
        group = NULL;
        }
    return(group);
    }
于 2014-10-13T23:31:28.240 に答える
0

2019-10 後半からの更新、最近の状態

さまざまな EC 曲線を試した後、次の結果が得られました。

  • secp192k1: 動作しません
  • secp224k1: 動作しません
  • secp224r1: 動作しません
  • secp256k1: 動作しません
  • secp384r1: 動作します
  • secp521r1: 動作します

これらは、現在の openssl と mbedtls の両方のドキュメントでサポートされている曲線です。

考えられる理由は、おそらくいくつかのセキュリティ上の理由で、楕円曲線パラメーターと適用された TLS 暗号の間の変換がシームレスではないことです。正確な理由を見つけるために時間を無駄にしませんでした。現在、secp384r1 を使用しています。

于 2019-10-29T16:03:19.613 に答える