【问题标题】:Can't set public/private key in OpenSSL无法在 OpenSSL 中设置公钥/私钥
【发布时间】:2015-07-07 21:04:02
【问题描述】:

我正在尝试从字符串将公钥和私钥设置为 C++ 中的 EVP_PKEY。然而,即使在网上看了几个例子之后,PKEY 总是显示为 NULL。这是重现问题的代码(这是私钥,但效果与公钥相同):

#include <openssl/evp.h>
#include <openssl/pem.h>
#include <string>
#include <iostream>

int main()
{
    EVP_PKEY *keypair;
    keypair = NULL;

    std::string privateKey = "-----BEGIN PRIVATE KEY-----MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCuKz6ENUUniXU9CelOgD6oTlmkxPWZoaeBUVXLwlh2aE4As/8RMaIpTsxq9M8UmY7L69GVHo51+wmACrW1ftEa3S5rVLRuOrwFNYGLUlrbji4huD5ipxS0MbxKE+lc/VYLTN26zPI8pl8Qb38eESiLXZ7uNO1XRisKxjixy/J4CMMDdn0UFTjKxXmdQluN67T1JlzGzALRKYFMLF8H+VLqhW6ygFE1OjjJ8zwQuP8t2mRBFLXwH1bwffXX4rUwAb+C9FXHWEn5SJv8aoj/9awEw7cYWa0eeAbl2TfPW+QcbzcITp9L9g/9/8M9rH0wqURCzv+z7P0Wkc2JrdcA6vIDAgMBAAECggEAHjFO8BpP96+jjEZIlJw0wHZ8ocynCs/0Or2/0sfJEBW61/JcGD3zb5fCZhQ0Rczs7TrfJSub5KX1GqZAo8rtMuv+3QpdEPLLn1eMMnu/VmpKYvwOjImMVER+8JSNEtqz7NeRZI2cvJjWyAGcFrlAvxAmugKg1k1Krt53+5JwYRBSWQb+05egOXVoQahBJbLWbWJrUFBjmsCAkF/1MvnJ9h2CAmrJIOWMjzWgs2MyUSzAE0I0vLG/mtlUXUGWA7EFAY6BNGWUaHdd6Cy2GhlCoEEL4gYATdtQK1k5r/5O54gTJq1rISEjicXp/qLiFIEa8feuCFGWfFQnIXlmvRZ/gQKBgQDkA8gdQ5XTBQHdcasIeNjJTgmB1W0cugYmUB01O0Kk0O5sVAh0LtWkIF6Tw5Od3olYRt/UNpegOvYoc+lm3kLS14NPcd5P3Zdl/i9NcWq8QF3uNzT5NfLi2nh8lyH2q41Koc2skRQsIQkZEOgLjP2+n3SsZf0PBOE9rYeO9rkSwwKBgQDDi6CWVOSH4suSGLJeauc/j7/MwMAtM7r5cOegh1tJZrAhiL7DXeWM9iT2VWU+9fiH16Je6+0PuXPmkcj3T/E/fSWQ+6n0YjnvIuyQGxMFXW2Zwssxgv51iD+EO88lFD+2wR6YUHl0wPeSQTUvHM3xUp/uOG0yUvoCijqxFCYvwQKBgCvy7qd1V3ONC4b7WdQQNvjWKc70rEtVL8pCtt6DxZyvCMWojNiYDmXMN26Ty+gp9J8nSg1FWIRx2PCDJwHE5WxuTckKUadjNsNZ8xQiQEh4v6Ii0fsXAvHm2kJpfwpklp9EALi6XgEDfRVvxMo1KtOLOJniLpyufBu/TtmnhJSxAoGAG+CI+UWK+vBTMzXAIAO/iek1X7xO6WLJkgwNiW4ijnlMPMug3ntBYXIp3NBZybsJPlx4cm3R8v7uTf2Ul+VWsEVoGJ44IXXranMhJH4nnQkvuc7yZtGU8y6EV5arNk8Hskcf1HkMh5+G69vN+DR0C6ZK1IxIzPbVW41XRq1nsEECgYBmtbY5dIvRemh4FdsMjdUuQcurvyQpEIwdczWurRXfKCuWtbVvn1arTQ/nL+kUixMjPueBInX90vxP+ptoPAHXOMKuZx+bFNwIQZ+OIBQ1WPUG8nV4o7tRZOkIPSy8YVz8UFQuuA6WF5W2kh3gc3iPrQt5JjspkWPDuC1taQo/pw==-----END PRIVATE KEY-----";

    BIO *bio = BIO_new(BIO_s_mem());
    if(BIO_write(bio, (unsigned char*)privateKey.c_str(), (size_t)privateKey.size()) != (int)privateKey.size())
    {
        BIO_free_all(bio);
        return 0;
    }

    PEM_read_bio_PrivateKey(bio, &keypair, NULL, NULL);

    BIO_free_all(bio);

    if(keypair == NULL)
    {
        std::cout << "error";
    }
    else
    {
        return 0;
    }
}

我做错了什么?

【问题讨论】:

    标签: c++ c encryption openssl rsa


    【解决方案1】:

    您传递的私钥无效;它缺少换行符。需要在-----BEGIN PRIVATE KEY----- 标头之后有一个,在相应的页脚之前有一个,在正文中每 64 个字符之后有一个,例如

    std::string privateKey = "-----BEGIN RSA PRIVATE KEY-----\n"
        "MIIEogIBAAKCAQEAris+hDVFJ4l1PQnpToA+qE5ZpMT1maGngVFVy8JYdmhOALP/\n"
        "ETGiKU7MavTPFJmOy+vRlR6OdfsJgAq1tX7RGt0ua1S0bjq8BTWBi1Ja244uIbg+\n"
        /* ... */
        "5y/pFIsTIz7ngSJ1/dL8T/qbaDwB1zjCrmcfmxTcCEGfjiAUNVj1BvJ1eKO7UWTp\n"
        "CD0svGFc/FBULrgOlheVtpId4HN4j60LeSY7KZFjw7gtbWkKP6c=\n"
        "-----END RSA PRIVATE KEY-----";
    

    【讨论】:

    • “您传递的私钥无效;它缺少换行符。” - 我很惊讶 OpenSSL 还没有解决这个问题......这是一个任意限制RFC 821RFC 1421 中的 1000 个字符。没有理由因为缺少新行而导致处理失败,这些新行会立即被删除。
    • 那些 RFC 在这里并不真正相关,因为这不是电子邮件。 RFC 7468 实际上设置了更严格的要求,即每行必须包含“除了最后一行之外,正好 64 个字符”。但是,即使不是这种情况,也需要将页眉/拖尾行与数据分开,因此仍然至少缺少两个换行符。
    • 为了完整起见,切入这些例程时,RFC 7468 并不存在 :) Base64 编码器来自电子邮件 RFC,而 PEM 编码来自 PEM RFC。但很高兴看到这种行为最终被召唤出来。你对封装的标题边界是正确的 - 它们确实需要新的线条来描绘它们。
    猜你喜欢
    • 2011-07-19
    • 1970-01-01
    • 1970-01-01
    • 2018-10-07
    • 2012-04-05
    • 1970-01-01
    • 2016-09-20
    • 2017-12-18
    • 2017-04-29
    相关资源
    最近更新 更多