【问题标题】:Some elliptic curves in openssl give "no shared cipher" errorsopenssl 中的一些椭圆曲线给出“无共享密码”错误
【发布时间】:2013-05-02 09:32:55
【问题描述】:

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

  • openssl ecparam -out ec_$curve.key -name $curve -genkey创建一个椭圆曲线密钥对,在openssl ecparam -list_curves中foreach $curve

  • 使用openssl req -x509 -new -days 365 -key ec_$curve.key -out ec_$curve.crt -subj $SOME_SUBJ为每个ec_$curve.key生成自签名证书

  • 对于每个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 线索的人,这到底是怎么回事?

【问题讨论】:

    标签: openssl


    【解决方案1】:

    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。很可能,这就是原因。

    【讨论】:

    • 这是 RFC 4492 - 用于传输层安全 (TLS) 的椭圆曲线加密 (ECC) 密码套件
    • 我用的是secp192k1(18),问题存在。
    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

      2019-10 年末更新,近期状态

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

      • secp192k1:不起作用
      • secp224k1 :不起作用
      • secp224r1:不起作用
      • secp256k1:不起作用
      • secp384r1:确实有效
      • secp521r1:确实有效

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-05-07
        • 2015-05-09
        • 1970-01-01
        相关资源
        最近更新 更多