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

openssl中的一些椭圆曲线给出;“无共享密码”;错误,openssl,Openssl,当使用openssl s_服务器/s_客户端组合时,生成密钥对的某些曲线似乎不起作用。我已使用以下方法对此进行了验证: 使用openssl ecparam-out ec_$curve.key-name$curve-genkey,foreach$curveinopenssl ecparam-list_curves 使用openssl req-x509-新建-365天-密钥ec_$curve.key-out ec_$curve.crt-subc$SOME_subc为每个ec_$curve.key生

当使用openssl s_服务器/s_客户端组合时,生成密钥对的某些曲线似乎不起作用。我已使用以下方法对此进行了验证:

  • 使用
    openssl ecparam-out ec_$curve.key-name$curve-genkey
    ,foreach
    $curve
    in
    openssl ecparam-list_curves

  • 使用
    openssl req-x509-新建-365天-密钥ec_$curve.key-out ec_$curve.crt-subc$SOME_subc为每个
    ec_$curve.key
    生成自签名证书

  • 对于每个
    ec_$curve.key
    ,执行以下操作:在一个窗口中,
    openssl s_服务器-cert ec_$curve.crt-key ec_$curve.key-accept 10000
    ,另一个
    openssl s_客户端-主机本地主机-端口10000

我开始握手:

使用默认的temp DH参数
使用默认的temp ECDH参数
接受
错误
8606155664:错误:1408A0C1:SSL例程:SSL3_GET_CLIENT_HELLO:无共享密码:s3_srvr.c:1355:
关闭SSL
连接已关闭

仅适用于使用以下曲线创建的键对:
c2.
曲线(例如,
c2pnb163v1
)、
prime192v[23]
prime239.
sec.1[123].
曲线。所有其他曲线都可以正常工作

这对我来说毫无意义。s_客户端应该能够与s_服务器通信,因此这可能是OpenSSL错误,或者我配置了客户端或服务器,或者两者都配置错误。我尝试在服务器端添加命名的_曲线参数,但这并没有改善情况。OpenSSL版本为1.0.1e


那么,有更多加密/电子商务线索的人,这到底是怎么回事

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第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_组对象的代码,该对象可用于生成自定义曲线的关键点,其参数与命名曲线的参数匹配:

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);
    }
2019-10年末更新,最近状态

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

  • secp192k1
    :不工作
  • secp224k1
    :不工作
  • secp224r1
    :不工作
  • secp256k1
    :不工作
  • secp384r1
    :工作正常
  • secp521r1
    :工作正常
这些是当前openssl和mbedtls文档都支持的曲线


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

这是RFC 4492-传输层安全的椭圆曲线加密(ECC)密码套件(TLS)。我使用的是secp192k1(18),问题存在。