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

qua*_*ack 5 openssl

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

  • 使用创建一个椭圆曲线键对openssl ecparam -out ec_$curve.key -name $curve -genkey,foreach $curveinopenssl ecparam -list_curves

  • 生成每个自签名证书ec_$curve.keyopenssl 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线索的人,这到底是怎么回事?

Ole*_*ryb 2

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

'openssl ecparam' 中还有 -C 选项,允许为命名曲线生成 C 代码,例如

openssl ecparam  -name prime256v1  -C
Run Code Online (Sandbox Code Playgroud)

将生成用于创建 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);
    }
Run Code Online (Sandbox Code Playgroud)