使用工具

  • Qt Creator 16.0.1 (Community)
  • vscode

具体逻辑

本次应用场景为qt和服务端互相交换非对称加密后的对称密钥,用于弥补rsa加密字节容量过少的缺点,简称混合加密

图片

实现代码

qt客户端

  • 定义指针,可复用性
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
EVP_PKEY* JsonCrypto::loadPublicKey() {
QFile file(m_pubPath);
if (!file.open(QIODevice::ReadOnly)) return nullptr;
QByteArray data = file.readAll();
BIO *bio = BIO_new_mem_buf(data.constData(), data.size());
EVP_PKEY *pkey = PEM_read_bio_PUBKEY(bio, nullptr, nullptr, nullptr);
BIO_free(bio);
return pkey;
}

EVP_PKEY* JsonCrypto::loadPrivateKey() {
QFile file(m_privPath);
if (!file.open(QIODevice::ReadOnly)) return nullptr;
QByteArray data = file.readAll();
BIO *bio = BIO_new_mem_buf(data.constData(), data.size());
EVP_PKEY *pkey = PEM_read_bio_PrivateKey(bio, nullptr, nullptr, nullptr);
BIO_free(bio);
return pkey;
}
  • 生成非对称密钥(rsa)

    实现功能如下

    • 返回base64编码后的密钥,方便传输
    • 保存客户端生成的私钥
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
QString JsonCrypto::generateKey() {
EVP_PKEY *pkey = EVP_RSA_gen(2048);
if (!pkey) return {};

// Save private key
QFile privFile(m_privPath);
if (!privFile.open(QIODevice::WriteOnly)) {
EVP_PKEY_free(pkey);
return {};
}
BIO *privBio = BIO_new(BIO_s_mem());
PEM_write_bio_PrivateKey(privBio, pkey, nullptr, nullptr, 0, nullptr, nullptr);
BUF_MEM *privPtr;
BIO_get_mem_ptr(privBio, &privPtr);
privFile.write(privPtr->data, static_cast<int>(privPtr->length));
privFile.close();
BIO_free(privBio);

// Get public key
BIO *pubBio = BIO_new(BIO_s_mem());
PEM_write_bio_PUBKEY(pubBio, pkey);
BUF_MEM *pubPtr;
BIO_get_mem_ptr(pubBio, &pubPtr);
QByteArray pubPem(pubPtr->data, static_cast<int>(pubPtr->length));
BIO_free(pubBio);
EVP_PKEY_free(pkey);

QByteArray b64Data = pubPem.toBase64();
return QString::fromLatin1(b64Data);
}
  • 报错客户端生成的私钥
1