5

使用 openssl s_server/s_client 组合时,生成密钥对的某些曲线似乎不起作用。我已经使用以下方法验证了这一点:

  • openssl ecparam -out ec_$curve.key -name $curve -genkey用, foreach$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,做:在一个窗口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.*曲线(例如c2pnb163v1prime192v[23]prime239.*sec.1[123].*曲线。所有其他曲线工作正常。

这对我来说毫无意义。s_client 应该能够与 s_server 通信,所以要么这是一个 OpenSSL 错误,要么我配置了客户端或服务器或两者都错误。我尝试在服务器端添加 -named_curve 参数,但这并没有改善。OpenSSL 版本是 1.0.1e。

那么,有更多加密/EC 线索的人,这到底是怎么回事?

4

3 回答 3

4

TLS 标准仅定义了对这些曲线的支持:

    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)

虽然 OpenSSL 可以生成具有其他曲线的证书,但它们不能用于 SSL/TLS。很可能,这就是原因。

于 2013-05-02T13:28:13.367 回答
2

根据 RFC 4492 的第 5.1.1 节,也支持具有任意参数的曲线(请参见下面的 optional_explicit_prime_curves)。这意味着如果您找到要测试的每条曲线的定义和所有 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 回答