3.1、从文件中读取密钥对

3.1.1、BIO_new_file

用于创建适用于文件 I/O 的 BIO 对象,它允许将文件与 BIO 抽象接口结合使用,以便进行读取或写入文件的操作

BIO *BIO_new_file(const char *filename, const char *mode);

参数解释:

  • filename:要进行读取或写入的文件的名称或路径。
  • mode:表示文件操作模式的字符串。常见的模式包括:

    • "r":只读模式。
    • "w":写入模式,如果文件不存在则创建,如果文件存在则截断。
    • "a":追加模式,在文件末尾写入数据。
    • "rb":以二进制格式打开文件进行只读操作。
    • "wb":以二进制格式打开文件进行写入操作。
    • "ab":以二进制格式打开文件进行追加操作。

返回值:

  • 成功:指向新创建的文件 BIO 对象的指针。
  • 失败:返回 NULL
BIO* bio = BIO_new_file(fileName.data(), "rb");
assert(bio != NULL);
3.1.2、PEM_read_bio_PUBKEY

从一个 BIO 对象(在内存中的数据流)中读取 PEM 编码的公钥,PEM_read_bio_PUBKEY 函数读取 PEM 编码的公钥,并将结果存储在 EVP_PKEY 结构体中。

#include <openssl/pem.h>

EVP_PKEY *PEM_read_bio_PUBKEY(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, void *u);

该函数接受以下参数:

  • bp:指向 BIO 对象的指针,可用于读取 PEM 文件中的数据或从其他数据源读取 PEM 格式的数据。
  • x:指向 EVP_PKEY 指针的指针,用于接收读取的公钥。
  • cb:一个回调函数,用于处理密码(如果 PEM 文件有密码保护)。
  • u:用户自定义数据,在回调函数中可以使用。

返回值:

  • 成功,返回 EVP_PKEY 指针
  • 失败,返回 NULL。
if (keyType == PUBLICKEY)
{
    PEM_read_bio_PUBKEY(bio, &m_publicKey, NULL, NULL);
}
3.1.3、PEM_read_bio_PrivateKey

用于从一个 BIO 对象(在内存中的数据流)中读取 PEM 编码的私钥,PEM_read_bio_PrivateKey 函数读取 PEM 编码的公钥,并将结果存储在 EVP_PKEY 结构体中。

#include <openssl/pem.h>

EVP_PKEY *PEM_read_bio_PrivateKey(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, void *u);

该函数接受以下参数:

  • bp:指向 BIO 对象的指针,可用于读取 PEM 文件中的数据或从其他数据源读取 PEM 格式的数据。
  • x:指向 EVP_PKEY 指针的指针,用于接收读取的私钥。
  • cb:一个回调函数,用于处理密码(如果 PEM 文件有密码保护)。
  • u:用户自定义数据,在回调函数中可以使用。

返回值:

  • 成功,返回 EVP_PKEY 指针
  • 失败,返回 NULL。
else
{
    PEM_read_bio_PrivateKey(bio, &m_privateKey, NULL, NULL);
}
记得调用BIO_free(bio);函数释放BIO对象
完整示例:
RSACrypto::RSACrypto(const QByteArray& fileName, KeyType keyType, QObject* parent)
{
    BIO* bio = BIO_new_file(fileName.data(), "rb");
    assert(bio != NULL);
    if (keyType == PUBLICKEY)
    {
        PEM_read_bio_PUBKEY(bio, &m_publicKey, NULL, NULL);
    }
    else
    {
        PEM_read_bio_PrivateKey(bio, &m_privateKey, NULL, NULL);
    }
    BIO_free(bio);
}

3.2 释放密钥对对象

3.2.1、EVP_PKEY_free
void EVP_PKEY_free(EVP_PKEY *pkey);

参数解释:

  • pkey: 要释放的私钥或公钥的EVP_PKEY对象
RSACrypto::~RSACrypto()
{
    if (m_privateKey)
    {
        EVP_PKEY_free(m_privateKey);
    }
    if (m_publicKey)
    {
        EVP_PKEY_free(m_publicKey);
    }
}