使用C ++以十六进制格式将公钥转换为EC_KEY

时间:2019-07-15 22:33:07

标签: c++ openssl

我在C ++代码中有一个十六进制格式的公共密钥。我必须将此公钥转换为openssl用来验证签名的EC_KEY结构。问题是我无法将十六进制字符串转换为openssl可以从其生成公钥的pem格式。

已尝试: 1.我将十六进制字符串转换为字节。 (我想这会转换为ASCII格式) 2.将此字节字符串转换为base64(ascii格式为base64编码) 3.使用PEM_read_bio_EC_PUBKEY获取公钥(读为pem) 4. EC_KEY_check_key失败。

static const char b64_table[65] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

static std::string base64_encode(const ::std::string& bindata)
{
    using ::std::string;
    using ::std::numeric_limits;

    if (bindata.size() > ((numeric_limits<string::size_type>::max)() / 4u) * 3u)
    {
        throw ::std::length_error("Converting too large a string to base64.");
    }

    const ::std::size_t binlen = bindata.size();
    // Use = signs so the end is properly padded.
    string retval((((binlen + 2) / 3) * 4), '=');
    ::std::size_t outpos = 0;
    int bits_collected = 0;
    unsigned int accumulator = 0;
    const string::const_iterator binend = bindata.end();

    for (string::const_iterator i = bindata.begin(); i != binend; ++i) {
        accumulator = (accumulator << 8) | (*i & 0xffu);
        bits_collected += 8;
        while (bits_collected >= 6) {
            bits_collected -= 6;
            retval[outpos++] = b64_table[(accumulator >> bits_collected) & 0x3fu];
        }
    }
    if (bits_collected > 0) { // Any trailing bits that are missing.
        assert(bits_collected < 6);
        accumulator <<= 6 - bits_collected;
        retval[outpos++] = b64_table[accumulator & 0x3fu];
    }
    assert(outpos >= (retval.size() - 2));
    assert(outpos <= retval.size());
    return retval;
}


std::string HexToBytes(const std::string& hex)
{
    std::string bytes;

    for (unsigned int i = 0; i < hex.length(); i += 2) {
        std::string byteString = hex.substr(i, 2);
        char byte = (char)strtol(byteString.c_str(), NULL, 16);
        bytes.push_back(byte);
    }

    return bytes;
}

int main(int argc, char* argv[])
{
    // Set up the public key.... 
    std::string sPubKeyString = "E3A7E51FE102286D071026111088F680761FDCD7031E3D56244BBE07451601E78AD08AD40EADCF380900985A1FAB94DE6D02DB91920F1144E9EBC4E248444969";

    std::string sKeyInAscii = HexToBytes(sPubKeyString);

    std::string sPub64(base64_encode(sKeyInAscii));
    std::string sKeyInPem = std::string("-----BEGIN PUBLIC KEY-----\n") + sPub64 + std::string("\n-----END PUBLIC KEY-----");

    const char* pzKey = sKeyInPem.c_str();
    std::unique_ptr< BIO, std::function<void(BIO*)>> bo(BIO_new(BIO_s_mem()), [](BIO* b) { BIO_free(b); });
    BIO_write(bo.get(), pzKey, strlen(pzKey));
    std::unique_ptr< EC_KEY, std::function<void(EC_KEY*)>> zPublicKey(EC_KEY_new_by_curve_name(NID_X9_62_prime256v1), [](EC_KEY* b) { EC_KEY_free(b); });
    EC_KEY* pPubKey = zPublicKey.get();
    PEM_read_bio_EC_PUBKEY(bo.get(), &pPubKey, NULL, NULL);

    if (EC_KEY_check_key(pPubKey) == 1) {
        printf("EC Key valid.\n");
    }
    else {
        printf("EC Key Invalid!\n");
    }
}

此代码显示EC密钥无效。我不知道我在做什么错。预先感谢

0 个答案:

没有答案