openssl中的一些椭圆曲线给出“无共享密码”错误

时间:2013-05-02 09:32:55

标签: openssl

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

  • 使用openssl ecparam -out ec_$curve.key -name $curve -genkey

  • 中的$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.*曲线(例如,c2pnb163v1),prime192v[23]prime239.*sec.1[123].*曲线。所有其他曲线都可以正常工作。

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

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

3 个答案:

答案 0 :(得分: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。最有可能的是,这就是原因。

答案 1 :(得分:2)

根据RFC 4492的第5.1.1节,也支持具有任意参数的曲线(参见下面的arbitrary_explicit_prime_curves)。这意味着如果您找到要测试的每条曲线的定义和所有EC参数,您可以通过openssl调用生成密钥,例如EC_GROUP_new_curve,EC_KEY_set_group,EC_KEY_get0_private_key,然后在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);
    }

答案 2 :(得分:0)

从2019-10年末开始更新,最近状态

尝试各种EC曲线后,我得到以下结果:

  • secp192k1:无效
  • secp224k1:无效
  • secp224r1:无效
  • secp256k1:无效
  • secp384r1:确实有效
  • secp521r1:确实有效

这些是当前的opensl和mbedtls文档都支持的曲线。

我怀疑,可能的原因是椭圆曲线参数与所应用的TLS密码之间的转换不是无缝的,可能出于某些安全原因。我没有浪费更多的时间来找到确切的原因-我现在使用secp384r1。