使用OpenSSL的KAS-ECC OnepassDH
我希望使用OpenSSL为KAS-ECC OnepassDH模式开发代码。这样做的逻辑可以在中找到。所附图像显示了完成此操作的步骤: 我尝试过这样做,如下所示:使用OpenSSL的KAS-ECC OnepassDH,openssl,Openssl,我希望使用OpenSSL为KAS-ECC OnepassDH模式开发代码。这样做的逻辑可以在中找到。所附图像显示了完成此操作的步骤: 我尝试过这样做,如下所示: make_peer() { peer = EC_POINT_new(group); c = BN_CTX_new(); EC_POINT_set_affine_coordinates_GFp(group, peer, x, y, c); } onepassDH() { unsi
make_peer() {
peer = EC_POINT_new(group);
c = BN_CTX_new();
EC_POINT_set_affine_coordinates_GFp(group, peer, x, y, c);
}
onepassDH() {
unsigned char Zs[256];
unsigned char Ze[256];
// derive private key from input public key
qsCAVSx = BN_bin2bn(qsCAVSx, qsCAVSxLength, qsCAVSx);
qsCAVSy = BN_bin2bn(qsCAVSy, qsCAVSyLength, qsCAVSy);
peerkey = make_peer(group, qsCAVSx, qsCAVSy);
if(NULL == peerkey)
goto fail;
// Other party key
ecKey = EC_KEY_new();
if ( ecKey == NULL ) {
LOG_ERROR("failed to create ecKey\n");
LOG_ERROR("OpenSSL reports: %s\n", ERR_error_string(ERR_get_error(), NULL));
goto fail;
}
EC_KEY_set_flags(ecKey, EC_FLAG_COFACTOR_ECDH);
if ( 0 == EC_KEY_set_group(ecKey, group) ) {
LOG_ERROR("cannot set group\n");
LOG_ERROR("OpenSSL reports: %s\n", ERR_error_string(ERR_get_error(), NULL));
goto fail;
}
if ( 0 == EC_KEY_generate_key(ecKey) ) {
LOG_ERROR("cannot generate key\n");
LOG_ERROR("OpenSSL reports: %s\n", ERR_error_string(ERR_get_error(), NULL));
goto fail;
}
//extract public key from other party's key pair
ec_ctx = BN_CTX_new();
if ( !ec_ctx ) {
LOG_ERROR("BN_CTX_new() returned NULL in %s at line %d\n", __FILE__, __LINE__);
LOG_ERROR("OpenSSL reports: %s\n", ERR_error_string(ERR_get_error(), NULL));
goto fail;
}
qeIUTx = BN_CTX_get(ec_ctx);
qeIUTy = BN_CTX_get(ec_ctx);
if ( !qeIUTx || !qeIUTy ) {
LOG_ERROR("BN_CTX_get() returned NULL in %s at line %d\n", __FILE__, __LINE__);
LOG_ERROR("OpenSSL reports: %s\n", ERR_error_string(ERR_get_error(), NULL));
goto fail;
}
grp = EC_KEY_get0_group(ecKey);
if ( grp == NULL ) {
LOG_ERROR("EC_KEY_get0_group() returned NULL!");
LOG_ERROR("OpenSSL reports: %s\n", ERR_error_string(ERR_get_error(), NULL));
goto fail;
}
pt = EC_KEY_get0_public_key(ecKey);
if ( pt == NULL ) {
LOG_ERROR("EC_KEY_get0_public_key() returned NULL!");
LOG_ERROR("OpenSSL reports: %s\n", ERR_error_string(ERR_get_error(), NULL));
goto fail;
}
meth = EC_GROUP_method_of(grp);
if ( meth == NULL ) {
LOG_ERROR("EC_GROUP_method_of() returned NULL\n");
LOG_ERROR("OpenSSL reports: %s\n", ERR_error_string(ERR_get_error(), NULL));
goto fail;
}
// this uses "grp", "pt", and "ctx" to set "tx" and "ty"
EC_POINT_get_affine_coordinates_GFp(grp, pt, qeIUTx, qeIUTy, ec_ctx);
qeIUTxLength = BN_num_bytes(qeIUTx);
qeIUTyLength = BN_num_bytes(qeIUTy);
zLength = (EC_GROUP_get_degree(group) + 7)/8;
ECDH_compute_key(Zs, zLength, peerkey, ecKey, 0);
// Generate ephemeral key
de_Key = EC_KEY_new();
if ( de_Key == NULL ) {
LOG_ERROR("failed to create ecKey\n");
LOG_ERROR("OpenSSL reports: %s\n", ERR_error_string(ERR_get_error(), NULL));
goto fail;
}
EC_KEY_set_flags(de_Key, EC_FLAG_COFACTOR_ECDH); // <--- this is the FIPS-dependant part
if ( 0 == EC_KEY_set_group(de_Key, group) ) {
LOG_ERROR("cannot set group\n");
LOG_ERROR("OpenSSL reports: %s\n", ERR_error_string(ERR_get_error(), NULL));
goto fail;
}
if ( 0 == EC_KEY_generate_key(de_Key) ) {
LOG_ERROR("cannot generate key\n");
LOG_ERROR("OpenSSL reports: %s\n", ERR_error_string(ERR_get_error(), NULL));
goto fail;
}
ec_ctx = BN_CTX_new();
if ( !ec_ctx ) {
LOG_ERROR("BN_CTX_new() returned NULL in %s at line %d\n", __FILE__, __LINE__);
LOG_ERROR("OpenSSL reports: %s\n", ERR_error_string(ERR_get_error(), NULL));
goto fail;
}
qeIUTx = BN_CTX_get(ec_ctx);
qeIUTy = BN_CTX_get(ec_ctx);
if ( !qeIUTx || !qeIUTy ) {
LOG_ERROR("BN_CTX_get() returned NULL in %s at line %d\n", __FILE__, __LINE__);
LOG_ERROR("OpenSSL reports: %s\n", ERR_error_string(ERR_get_error(), NULL));
goto fail;
}
grp = EC_KEY_get0_group(de_Key);
if ( grp == NULL ) {
LOG_ERROR("EC_KEY_get0_group() returned NULL!");
LOG_ERROR("OpenSSL reports: %s\n", ERR_error_string(ERR_get_error(), NULL));
goto fail;
}
pt = EC_KEY_get0_public_key(de_Key);
if ( pt == NULL ) {
LOG_ERROR("EC_KEY_get0_public_key() returned NULL!");
LOG_ERROR("OpenSSL reports: %s\n", ERR_error_string(ERR_get_error(), NULL));
goto fail;
}
meth = EC_GROUP_method_of(grp);
if ( meth == NULL ) {
LOG_ERROR("EC_GROUP_method_of() returned NULL\n");
LOG_ERROR("OpenSSL reports: %s\n", ERR_error_string(ERR_get_error(), NULL));
goto fail;
}
// this uses "grp", "pt", and "ctx" to set "tx" and "ty"
EC_POINT_get_affine_coordinates_GFp(grp, pt, qeIUTx, qeIUTy, ec_ctx);
ECDH_compute_key(Ze, zLength, de_priv_key, ecKey, 0);
zLength = 2 * ((EC_GROUP_get_degree(group) + 7)/8);
memcpy(Z, Ze, zLength/2);
memcpy(Z+(zLength/2), Zs, zLength/2);
ECDH_compute_key(Z, zLength, peerkey, ecKey, 0);
// Hash the sharesecret
ctx = EVP_MD_CTX_create();
if ( 0 == EVP_DigestInit_ex(ctx, md, NULL) ) {
LOG_ERROR("error in %s, line%d; sha_type %d\n", __FILE__, __LINE__, md->md_size * 8);
ERR_print_errors_fp(stderr);
goto fail;
}
if ( 0 == EVP_DigestUpdate(ctx, Z, zLength) ) {
LOG_ERROR("error in %s, line%d\n", __FILE__, __LINE__);
ERR_print_errors_fp(stderr);
goto fail;
}
if ( 0 == EVP_DigestFinal_ex(ctx, iutTag, &count) ) {
LOG_ERROR("error in %s, line%d\n", __FILE__, __LINE__);
ERR_print_errors_fp(stderr);
goto fail;
}
}
}
KAS-ECC alg的问题是,我在网上看不到多少帮助来实现这一点。我找到了几个链接:,但在为OnePassDH编写代码方面帮不了我多少忙。有人能告诉我我的代码有什么问题吗?现在代码本身不会抛出错误,但对任何输入都会给出相同的结果。摘要 我已经通过OpenSSL实现了ECDH,并使用测试向量进行测试。我希望这个答案会有所帮助
算法描述 注意:下面的伪代码只是一条路径,因为它是从更复杂的系统简化而来的。将不会提到许多确切的类型或进行错误检查 小结:从曲线创建EC_组,从公钥和私钥的字节数组创建EC_密钥、EVP_PKEY结构,为DH操作创建EVP_PKEY_上下文,派生密钥
auto order = EC_GROUP_new_by_curve_name(NID_curve)
std::vector<uint8_t> otherKey = getOtherKey();
EVP_PKEY_derive_set_peer(pkeyCtx, publicEvpPkey);
size_t length = 0;
EVP_PKEY_derive(pkeyCtx, nullptr, &length);
std::vector<uint8_t> secret(length);
EVP_PKEY_derive(pkeyCtx, secret.data(), &length);
这里[QCAVSx,QCAVSy]和[QIUTx,QIUTy]-分别是CAV(远程用户)和IUT(用户)的公共向量。为了将此数据用作OpenSSL的公钥,我通过连接两个坐标并在开头添加“04”(04是未压缩表单的标记):04[x坐标][y坐标],从这两个坐标创建了未压缩表单。
dIUT是IUT的私钥。
ZIUT是一个秘密,它是参考结果
我将dIUT和未压缩的QCAVS公钥作为字节数组,通过BN_bin2bn()函数与OpenSSL一起使用,在上述算法的帮助下,我的测试成功了
std::vector<uint8_t> otherKey = getOtherKey();
//Create EC_KEY
auto key = EC_KEY_new();
EC_KEY_set_group(key, group);
ECDSA_set_method(key, ECDSA_get_default_method());
EC_KEY_set_private_key(key, prvKey);
//Create EVP_PKEY and set EC_KEY there
auto pkey = EVP_PKEY_new();
EVP_PKEY_set1_EC_KEY(pkey, key);
//Create EVP_PKEY for public key:
auto publicEcKey = EC_KEY_new();
EC_KEY_set_group(publicEcKey, group);
ECDSA_set_method(publicEcKey, ECDSA_get_default_method());
EC_POINT point = EC_POINT_new(group);
EC_POINT_oct2point(group, point, otherKey.data(), otherKey.size());
EC_KEY_set_public_key(publicEcKey, point);
auto publicEvpPkey = EVP_PKEY_new();
EVP_PKEY_set1_EC_KEY(publicEvpPkey, publicEcKey);
//Create EVP_PKEY_CTX
auto pkeyCtx = EVP_PKEY_CTX_new(pkey, nullptr);
EVP_PKEY_derive_init(pkeyCtx);
EVP_PKEY_derive_set_peer(pkeyCtx, publicEvpPkey);
size_t length = 0;
EVP_PKEY_derive(pkeyCtx, nullptr, &length);
std::vector<uint8_t> secret(length);
EVP_PKEY_derive(pkeyCtx, secret.data(), &length);
[P-192]
COUNT = 0
QCAVSx = 42ea6dd9969dd2a61fea1aac7f8e98edcc896c6e55857cc0
QCAVSy = dfbe5d7c61fac88b11811bde328e8a0d12bf01a9d204b523
dIUT = f17d3fea367b74d340851ca4270dcb24c271f445bed9d527
QIUTx = b15053401f57285637ec324c1cd2139e3a67de3739234b37
QIUTy = f269c158637482aad644cd692dd1d3ef2c8a7c49e389f7f6
ZIUT = 803d8ab2e5b6e6fca715737c3a82f7ce3c783124f6d51cd0