【问题标题】:Load public key with openssl - invalid encoding使用 openssl 加载公钥 - 无效编码
【发布时间】:2023-03-10 06:46:01
【问题描述】:

我开始使用 openssl。 我想使用公钥来检查签名。但是现在,我无法使用 openssl 读取我的公钥。

这是我的源代码:

#include <iostream>

#include <openssl/ec.h>
#include <openssl/evp.h>
#include <openssl/err.h>

bool verifyPublicKey(const std::string &sRawPublicKey);
void printAllError();


int main(int argc, char* argv[])
{
    if (argc < 2) {
        std::cerr << "Usage: " << argv[0] << " PUBLIC KEY" << std::endl;
        return EXIT_FAILURE;
    }

    std::string sPublicKey = argv[1];

    std::cout << "Key: " << sPublicKey << std::endl;

    bool bRes = verifyPublicKey(sPublicKey);

    if (!bRes)
    {
        std::cerr << "verifyPublicKey failled" << std::endl;
        return EXIT_FAILURE;
    }

    return EXIT_SUCCESS;
}

bool verifyPublicKey(const std::string &sRawPublicKey)
{
    bool bRes = false;

    EC_KEY *eckey = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
    EC_KEY_set_conv_form(eckey, POINT_CONVERSION_UNCOMPRESSED);

    unsigned char *p_RawPublicKey = new unsigned char[sRawPublicKey.length() + 1];
    std::copy(sRawPublicKey.begin(), sRawPublicKey.end(), p_RawPublicKey);
    const unsigned char *pubkey_raw_p = p_RawPublicKey;

    o2i_ECPublicKey(&eckey, &pubkey_raw_p, sRawPublicKey.size());

    if (!EC_KEY_check_key(eckey))
    {
        EC_KEY_free(eckey);
        bRes = false;
        printAllError();
    }
    else
    {
        EC_KEY_free(eckey);
        bRes = true;
    }

    return bRes;
}

void printAllError()
{
    while (ERR_peek_last_error() != 0)
    {
        std::cerr << ERR_error_string(ERR_get_error(), nullptr) << std::endl;
    }
}

我使用以下公钥运行它:

3059301306072A8648CE3D020106082A8648CE3D03010703420004E297417036EB4C6404CC9C2AC4F28468DD0A92F2C9496D187D2BCA784DB49AB540B9FD9ACE0BA49C8532825954755EC10246A71AF2AEE9AEC34BE683CDDFD212

ASN.1 解码器:

SEQUENCE {    
    SEQUENCE {
        OBJECTIDENTIFIER 1.2.840.10045.2.1 (ecPublicKey)
        OBJECTIDENTIFIER 1.2.840.10045.3.1.7 (P-256)    
    }
    BITSTRING 0x04E297417036EB4C6404CC9C2AC4F28468DD0A92F2C9496D187D2BCA784DB49AB540B9FD9ACE0BA49C8532825954755EC10246A71AF2AEE9AEC34BE683CDDFD212
    : 0 unused bit(s) 
}

使用 ASN.1,我注意到我使用的密钥格式正确:0x04 ||十六进制(x) ||十六进制(y),z = 0x04。

程序的输出如下:

Key: 3059301306072A8648CE3D020106082A8648CE3D03010703420004E297417036EB4C6404CC9C2AC4F28468DD0A92F2C9496D187D2BCA784DB49AB540B9FD9ACE0BA49C8532825954755EC10246A71AF2AEE9AEC34BE683CDDFD212

错误:10067066:椭圆曲线例程:ec_GFp_simple_oct2point:无效编码

错误:10098010:椭圆曲线例程:o2i_ECPublicKey:EC lib

错误:1010206A:椭圆曲线例程:ec_key_simple_check_key:point at infinity verifyPublicKey 失败

我迷路了。你有解释吗? 此外,是否可以通过仅给出 x 和 y(没有 ASN.1 标头)来更进一步。

谢谢

【问题讨论】:

    标签: c++11 openssl public-key ecdsa


    【解决方案1】:

    看起来您应该将原始点提供给函数 o2i_ECPublicKey(),而不使用 ASN.1 框架。

    【讨论】:

      猜你喜欢
      • 2015-05-14
      • 1970-01-01
      • 2011-06-05
      • 2013-06-09
      • 1970-01-01
      • 2020-03-15
      • 1970-01-01
      • 1970-01-01
      • 2012-04-14
      相关资源
      最近更新 更多