错误:0906D06C:PEM例程:PEM_read_bio:无启动

时间:2018-03-17 03:34:34

标签: c++ windows qt openssl

得到这个非常烦人的错误。 error:0906D06C:PEM routines:PEM_read_bio:no start

代码:

RSA* publickey = cWrapper.getPublicKey("C:/rsa-stuff/public.pem");
QByteArray plain = "The man in the black fled into the desert and the gunslinger followed...";
QByteArray encrypted = cWrapper.encryptRSA(publickey, plain);

在encryptRSA()中:

const char* publicKeyStr = data.constData();
qDebug() << publicKeyStr;
BIO* bio = BIO_new_mem_buf((void*)publicKeyStr, -1);
BIO_set_flags(bio, BIO_FLAGS_BASE64_NO_NL);
RSA* rsaPubKey = PEM_read_bio_RSAPublicKey(bio, NULL, NULL, NULL);
if(!rsaPubKey) {
  qDebug() << "Could not load public key, " << ERR_error_string(ERR_get_error(), NULL); // error is here
}
BIO_free(bio);

这就是我读文件的方式:

QByteArray data;
QFile file(filename);

if(!file.open(QFile::ReadOnly))
{
    printf("Error reading file: %s\n", file.errorString());
    return data;
}

data = file.readAll();
file.close();
return data;

当我打印出publicKeyStr时,看起来很好。这是启用了所有字符的记事本++视图: public key in notepad++

任何人都知道我做错了什么?超级恼人的问题:(

首先,它不是this问题,因为我没有得到可靠的部分。无论如何,我确实尝试了所有的&#34;解决方案&#34;并且没有一个工作,同样的错误。

2 个答案:

答案 0 :(得分:0)

您的RSA公钥是SubjectPublicKeyInfo PEM格式,但您尝试使用PEM_read_bio_RSAPublicKey尝试以PKCS#1格式读取PEM RSA密钥来读取它。请尝试使用PEM_read_bio_RSA_PUBKEY

https://www.openssl.org/docs/man1.1.0/crypto/PEM_read_bio_RSAPublicKey.html

答案 1 :(得分:0)

我在移植的openSSL1.1.0f上遇到了同样的错误。从mqtt客户端连接中读取根证书时,在记录器中显示错误,直到我发现我已将ERR_put_error()直接转发到记录器,而在openssl中–“真实”错误处理保存在ERR_STATE错误缓冲区,因此有时(如在这种情况下),错误是“预期的”,并且ERR_STATE错误缓冲区被清除(在任何人检查之前)。

在crypto / pem / pem_info.c中,第65行:

i = PEM_read_bio(bp, &name, &header, &data, &len);
    if (i == 0) {
        error = ERR_GET_REASON(ERR_peek_last_error());
        if (error == PEM_R_NO_START_LINE) {
            ERR_clear_error();
            break;
        }
        goto err;

表示它通过PEM_read_bio中的BIO_gets运行,直到它返回零,并且,如果您得到此PEM_R_NO_START_LINE,那仅是说完成的一种方式。

但是到那时,错误已经出现在我的记录器中。因此,对于任何因错误而感到困惑的人,他或她直接从ERR_put_error转发,请在错误处理例程中使用ERR_print_errors_fp(stderr);。就我而言,因为我没有stderr,所以我做了一个补丁版本,例如:

    void errorhandling()
    {
        unsigned long l;
        char buf[256];
        const char *file, *data;
        int line, flags;

        while ((l = ERR_get_error_line_data(&file, &line, &data, &flags)) != 0)
        {
            ERR_error_string_n(l, buf, sizeof buf);
            printf("%s:%s:%d:%s\n", buf, file, line, (flags & ERR_TXT_STRING) ? data : "");
        }
    }