QT使用OpenSSL的接口实现RSA2的签名和验签

这篇具有很好参考价值的文章主要介绍了QT使用OpenSSL的接口实现RSA2的签名和验签。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

QT使用OpenSSL的接口实现RSA2的签名和验签

加密和签名在RSA加密算法中是两个不同的概念,虽然它们都涉及RSA密钥对的使用,但目的和应用场景有所不同。

  1. 加密 (encrypt/decrypt):
    • 加密:使用接收方的公钥对数据进行加密,只有拥有相应私钥的接收方才能解密数据。
    • 解密:使用接收方的私钥对加密数据进行解密,从而获得原始数据。
    • 加密用于保护数据的机密性,确保只有授权的人能够解密和读取数据。
  2. 签名 (sign/verify):
    • 签名:使用发送方的私钥对数据进行签名,产生一个数字签名。
    • 验证签名:使用发送方的公钥对数字签名进行验证,以确保数据的完整性和认证发送方身份。
    • 签名用于验证数据的完整性和真实性,确保数据在传输过程中没有被篡改。

在RSA加密算法中,加密和签名使用了相同的RSA密钥对,但是应用场景和目的不同。加密是为了保护数据的机密性,而签名是为了验证数据的完整性和真实性。

所以,虽然在技术上可以使用RSA密钥对进行加密和签名,但是在实际应用中,通常会根据具体的需求和安全要求来选择是使用加密还是签名功能。文章来源地址https://www.toymoban.com/news/detail-836771.html

#include <QCoreApplication>
#include <QDebug>
#include <openssl/rsa.h>
#include <openssl/pem.h>
#include <openssl/err.h>

// 加密函数
QByteArray encryptData(const QByteArray &data, RSA *publicKey) {
    int rsaLen = RSA_size(publicKey);
    unsigned char *encryptBuffer = new unsigned char[rsaLen];
    int result = RSA_public_encrypt(data.size(), reinterpret_cast<const unsigned char*>(data.constData()), encryptBuffer, publicKey, RSA_PKCS1_PADDING);
    if (result == -1) {
        qWarning() << "Encryption failed.";
        return QByteArray();
    }
    return QByteArray(reinterpret_cast<char*>(encryptBuffer), result);
}

// 解密函数
QByteArray decryptData(const QByteArray &data, RSA *privateKey) {
    int rsaLen = RSA_size(privateKey);
    unsigned char *decryptBuffer = new unsigned char[rsaLen];
    int result = RSA_private_decrypt(data.size(), reinterpret_cast<const unsigned char*>(data.constData()), decryptBuffer, privateKey, RSA_PKCS1_PADDING);
    if (result == -1) {
        qWarning() << "Decryption failed.";
        return QByteArray();
    }
    return QByteArray(reinterpret_cast<char*>(decryptBuffer), result);
}

RSA* createRSAFromPEM(const char* key, bool isPublicKey) {
    BIO *bio = BIO_new_mem_buf((void*)key, -1);
    if (bio == NULL) {
        qWarning() << "Failed to create BIO";
        return NULL;
    }

    RSA *rsa = NULL;
    if (isPublicKey) {
        rsa = PEM_read_bio_RSA_PUBKEY(bio, NULL, NULL, NULL);
    } else {
        rsa = PEM_read_bio_RSAPrivateKey(bio, NULL, NULL, NULL);
    }

    BIO_free(bio);
    return rsa;
}

int main(int argc, char *argv[])
{
    QCoreApplication app(argc, argv);
#if 0
    // 初始化 OpenSSL
    OpenSSL_add_all_algorithms();
    ERR_load_crypto_strings();

    // 生成RSA密钥对
    RSA *rsaKeyPair = RSA_generate_key(2048, RSA_F4, NULL, NULL);
    if (!rsaKeyPair) {
        qWarning() << "Failed to generate RSA key pair.";
        return 1;
    }
    // 获取公钥
    BIO *bioPub = BIO_new(BIO_s_mem());
    PEM_write_bio_RSAPublicKey(bioPub, rsaKeyPair);
    char *pubKeyBuffer;
    long pubKeyLength = BIO_get_mem_data(bioPub, &pubKeyBuffer);
    qDebug() << "Public Key: " << QByteArray(pubKeyBuffer, pubKeyLength);

    // 获取私钥
    BIO *bioPriv = BIO_new(BIO_s_mem());
    PEM_write_bio_RSAPrivateKey(bioPriv, rsaKeyPair, NULL, NULL, 0, NULL, NULL);
    char *privKeyBuffer;
    long privKeyLength = BIO_get_mem_data(bioPriv, &privKeyBuffer);
    qDebug() << "Private Key: " << QByteArray(privKeyBuffer, privKeyLength);

    // 待签名的数据
    const char *data = "Hello, world!";
    int dataSize = strlen(data);

    // 签名
    unsigned char signature[256]; // 2048 bit key size
    unsigned int signatureLength;
    if (RSA_sign(NID_sha256, (const unsigned char*)data, dataSize, signature, &signatureLength, rsaKeyPair) != 1) {
        qWarning() << "Failed to sign data.";
        return 1;
    }

    qDebug() << "Signature: " << QByteArray(reinterpret_cast<char*>(signature), signatureLength).toBase64();

    // 验证签名
    if (RSA_verify(NID_sha256, (const unsigned char*)data, dataSize, signature, signatureLength, rsaKeyPair) != 1) {
        qDebug() << "Signature is invalid!";
    } else {
        qDebug() << "Signature is valid!";
    }



    // 释放资源
    RSA_free(rsaKeyPair);
    BIO_free(bioPub);
    BIO_free(bioPriv);
    EVP_cleanup();
#endif

    /*

        支付宝的RSA2签名算法,支付宝开放平台SDK(https://docs.open.alipay.com/54)封装的签名工具类进行签名,一般的流程如下:

        签名 (RSA2 Sign):
            使用商户私钥对数据进行签名,生成数字签名。
            将数字签名与数据一起发送给支付宝或其他服务端。
        验证签名 (RSA2 Verify):
            支付宝或服务端使用商户提供的公钥对接收到的数据和签名进行验证。
            验证签名的有效性,以确保数据的完整性和真实性。

        在这种情况下,商户通常会使用支付宝提供的公钥对支付宝返回的数据进行验签,以确保数据的完整性和真实性,防止数据被篡改
    */
    // 商户提供的公钥和私钥
    const char *pubKeyStr = "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArtwVzIpLvzzGxQ074EYCIyNj0k16YukrF27rEu7JFndms6FWWzLwX3QxTiQSN6tfbEwV5K67H5cCc4yesOJWdVA3ft023+V2I3hDS2jdRvQU5Rwju4mUisi12/aE5c1N6jkxpjzDGiUNYdwHEHzj+9awBlMusJ3B2U1fZDO5hoU39bxWJ9xgsEOmKT1VJBYeteIAyf0jwyeDBxIfw15NU+H31QRS4xbCDJ4DPKn3jjpvfBd/6h6fFT1Yj/FHbvzfabRZjnEAciNhUj+cOw6O5bYKnyNcNt1bjvhGBSVc3p+FaUKfkdGwNOA+haXraN+F+BBLuyTapSReawQo/BErIQIDAQAB\n-----END PUBLIC KEY-----";
    const char *privKeyStr = "-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCu3BXMiku/PMbFDTvgRgIjI2PSTXpi6SsXbusS7skWd2azoVZbMvBfdDFOJBI3q19sTBXkrrsflwJzjJ6w4lZ1UDd+3Tbf5XYjeENLaN1G9BTlHCO7iZSKyLXb9oTlzU3qOTGmPMMaJQ1h3AcQfOP71rAGUy6wncHZTV9kM7mGhTf1vFYn3GCwQ6YpPVUkFh614gDJ/SPDJ4MHEh/DXk1T4ffVBFLjFsIMngM8qfeOOm98F3/qHp8VPViP8Udu/N9ptFmOcQByI2FSP5w7Do7ltgqfI1w23VuO+EYFJVzen4VpQp+R0bA04D6Fpeto34X4EEu7JNqlJF5rBCj8ESshAgMBAAECggEAStXGPpOxd1b7ern/NizAHWm3/vlJt6sy1gSSdrfbN9JCEf6qhr12QmPn9hlZ8plVbXPiqsxdKVfnpKw5/lnfxrVeCt2B7rC1rth5dHyctxEfIC663Dg1anAb5NfMaM1E20k/BnZayYWyBH+2RkgtCksHaq2O/eeGXwnOGYRJklgZnO8inITJiSnnvuVbN9W+JvHCTcuHjKp/YOAXBJGAWDsuBbIaaeYAlXhrzSeUvBlQSljp7JZyauQ3hTXDZzAJ9HYergWMWkg/iCo6iOw5NulkNtiWosTO+A8wWHFgN+vok8itIDyXMpNCcZBz8EPDug/dBH1L2yPp+nln+YGvQQKBgQD7cf7BwgtlTqtEeLDtqMrhqCqcU+e8N4w7DHj2VzuYFnpTIHXqn4SWSP0gjF/os04NtHcEMIX8l8Ihtl4iu6ivvcvTjf0s1/gD2BD8m08EHACi9bf4if/3Q7tBTzgiRasFbS9WNDprycp9uKweB+zByPp+rYahJoWJyUd3M0U5CwKBgQCyBvJNdtW+8Ph27jOrHyMGLK07SIpUfGZz1O0PYrYoqj33WnOJKIz2y26jQiXS8nPvi/XgAEYiQkbD+uVIXGgJXoJFH8+78i/Ne42q/GtCniqR3SUrWRUD8GvRrLXyzytnmX1yLJSSHeICw7/Gp48iQCN2tOFlz/bX2/lsPrSAAwKBgGoACJHOJ9exbmoTJyNJgR3YMv5sMMkb8bYC8AuJgsn+z9qzWIJsdQyWAH/0LYp/7GvCpFnTyuhNYb2sj8q8qcRMktzAgvagpSGZuK+FGa51z57jT4crRgkLOKmzp8pq7EoBWW9R3T8Ldp3BeG3AkYKwI0m8BYFyJ+GKROJvbsM5AoGAA1J73RQ1ou2ORXHmhu/60FevF+cfpbn4k3rKvbnC2nlq1J3cgBfAoa5kLynB2PDrVvIOsZJvvJ3uAiRBeRs4Wcxos++HCePYHoaKu0Ego0qeUsCEvA1ahgtLh8soThKtpa5ImAPa9esW16RdhNCFrEb0Inf3qNW7roWNXwbAiY8CgYEA7B4NzyR47a2/QBHU7y20JpgLTkhwCHQRsmdqcuLXKQxM3+Twe3HHy7VV9JmL6XBo3yPP9ArmpbiP8z0XGainXR977eAmBALX55HBWvoNU0xzASKbMjEIHjOMa7KHl3cA1OkQMNHfk5x3gFt8io9ChTlMdbQEES3elg3ITkELnNI=\n-----END PRIVATE KEY-----";

    // 从字符串中加载公钥和私钥
    RSA *publicKey = createRSAFromPEM(pubKeyStr, true);
    RSA *privateKey = createRSAFromPEM(privKeyStr, false);

    // 加密和解密测试
    QByteArray originalData = "Hello, RSA2!";
    QByteArray encryptedData = encryptData(originalData, publicKey);
    QByteArray decryptedData = decryptData(encryptedData, privateKey);

    qDebug() << "Original Data: " << originalData;
    qDebug() << "Encrypted Data: " << encryptedData.toBase64();
    qDebug() << "Decrypted Data: " << decryptedData;

    // 待签名的数据
    const char *data = "Hello, world!";
    int dataSize = strlen(data);
    // 签名
    unsigned char signature[256]; // 2048 bit key size
    unsigned int signatureLength;
    if (RSA_sign(NID_sha256, (const unsigned char*)data, dataSize, signature, &signatureLength, privateKey) != 1) {
        qWarning() << "Failed to sign data.";
        return 1;
    }

    qDebug() << "Signature: " << QByteArray(reinterpret_cast<char*>(signature), signatureLength).toBase64();

    // 验证签名
    if (RSA_verify(NID_sha256, (const unsigned char*)data, dataSize, signature, signatureLength, publicKey) != 1) {
        qDebug() << "Signature is invalid!";
    } else {
        qDebug() << "Signature is valid!";
    }

    // 释放资源
    RSA_free(publicKey);
    RSA_free(privateKey);
    EVP_cleanup();

    return app.exec();
}

到了这里,关于QT使用OpenSSL的接口实现RSA2的签名和验签的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • openssl加解密和签名验签步骤操作记录

    使用 OpenSSL 进行 AES 的 ECB(电子密码本)模式加解密相对简单。以下是基本步骤: 生成 AES 密钥: 首先,你需要生成一个 AES 密钥。AES 支持 128、192 和 256 位的密钥长度。 加密数据: 使用 AES ECB 模式加密数据。这里以加密文件 message.txt 为例: 这里,aes_key.bin 是你的 AES 密钥

    2024年01月24日
    浏览(30)
  • OpenSSL 3.1.1 ECC 加密、解密、签名、验签(国密 sm2、sm3)

    openssl 3 默认废弃了 旧版本 (opessl 1.x) 的部分api 导致部分旧ecc 代码无法使用(可以通过配置编译选项打开) ,这里展示如何使用新接口用ECC 进行加密解密。 新接口是真的方便,基本上你都不需要懂啥密码学知识,对我们这种密码白痴来说太好了 头文件 生成密钥对 导出公

    2024年02月05日
    浏览(43)
  • 加密和验签

      大多数公共网络是不安全的,一切基于HTTP协议的请求/响应(Request or Response)都是可以被截获的、篡改、重放(重发)的。因此我们需要考虑以下几点内容: 防伪装攻击(案例:在公共网络环境中,第三方 有意或恶意 的调用我们的接口) 防篡改攻击(案例:在公共网络环境

    2024年02月07日
    浏览(21)
  • 从加密到签名:如何使用Java实现高效、安全的RSA加解密算法?

    目录 1. 接下来让小编给您们编写实现代码!请躺好 ☺ 1.1 配置application.yml文件 1.2 RSA算法签名工具类 1.3  RSA算法生成签名以及效验签名测试 1.4 RSA算法生成公钥私钥、加密、解密工具类 1.5 RSA算法加解密测试 我们为什么要使用RSA算法来进行加解密?  RSA 加密算法是一种非对

    2024年02月12日
    浏览(42)
  • nginx使用openssl自签名,实现https登录

    1.确认nginx是否已安装SSL模块 查验方法:进入sbin目录,执行以下语句,显示结果如标记所示则表示安装成功 ./nginx -V  2.确认系统以安装SSL工具,开始制作证书 选择一个存放证书的路径,执行以下语句即可: (1)生成密钥,得到文件private.key openssl genpkey -algorithm RSA -out private

    2024年02月14日
    浏览(33)
  • 如何配置支付宝密钥之如何配置普通 RSA2 密钥|保姆级教学(一)

    进行支付宝开发的第一步就是: 配置密钥 。 但是有很多小伙伴都不知道怎么配置,这篇文章将手把手帮你从头开始捋清如何配置支付宝密钥~ 这次首先放一下官方文档:[ 如何生成及配置 RSA2 密钥 ],大佬们也可以选择直接跟着文档流程来。 这次主要分享一下「 如何配置普

    2024年02月05日
    浏览(30)
  • C++调用openssl实现国标sm2签名算法的使用

    SM2算法基于ECC椭圆曲线算法,广泛用于区块链、HTTPS 等需要非对称加密的场景。是基于椭圆曲线数学理论实现的一种非对称加密算法。相比RSA,ECC优势是可以使用更短的密钥,来实现与RSA相当或更高的安全。 下面链接可以了解一些关于SM2的基础知识。 椭圆曲线加密算法(E

    2024年01月24日
    浏览(27)
  • c# .net framework 实现微信支付v3 h5支付 签名 验签

    接口文档:微信支付-开发者文档 (qq.com)    遇到的问题有   1、签名老验证不过去 :      生成的签名老验证不过    n 不要加转义符   2、 发送的请求老是400  使用工具请求正常。代码不行。   UserAgent = \\\"m.cnblogs.com/WebRequest\\\";    不要留空就行 网址可填自己的

    2024年02月05日
    浏览(35)
  • 区块链数字签名、验签,以及椭圆曲线算法JS库—elliptic的使用

    目录 一、简介 二、椭圆曲线密码elliptic 1、安装elliptic和js-sha3 2、Keccak256 3、签名过程

    2024年02月02日
    浏览(36)
  • Java基于BC包的实现SM2签名验签方案,以及SM2签名中bc包冲突的部分解决方法

    信创改造也有一段时间了,这里记录和总结一些关于SM2算法的知识点。 或 由于BC包版本多种多样,且实现SM2算法的过程和结果并不相同。因此在引入bc包时,需要考虑bc包版本的问题,否则将出现包冲突或 ClassNotFound 的问题。 这里特别强调 ,特别是进行SDK开发时,需询问接入

    2024年02月14日
    浏览(40)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包