Qt5使用openssl实现RSA数字签名
来源:互联网 发布:人物卡通设计软件 编辑:程序博客网 时间:2024/06/08 15:00
1、环境安装
win7 64
安装qt-opensource-windows-x86-5.9.0.exe或更高版本,下载地址
安装Win32OpenSSL-1_0_2L.exe 下载地址,最新版本可能因为pro配置问题,总不成功,希望大家提醒
2、在Qt5工程的pro中 填写
LIBS += -LC:/OpenSSL-Win32/lib/MinGW -llibeay32
LIBS += -LC:/OpenSSL-Win32/lib/MinGW -lssleay32
INCLUDEPATH += $$quote(C:/OpenSSL-Win32/include)
添加头文件
#include <openssl/rsa.h>
#include <openssl/pem.h>
#include <openssl/bn.h>
#include <openssl/bio.h>
#include <openssl/evp.h>
3、添加代码
void MainWindow::createRSAKey(){ //创建目录 QString strPath = "./key"; QDir dir; if(dir.exists(strPath) == false) { dir.mkpath(strPath);//创建目录 } BIGNUM *bne = BN_new(); int ret = BN_set_word(bne,RSA_F4);/* 设置随机数长度 */ RSA *rsa = RSA_new(); ret = RSA_generate_key_ex(rsa,1024,bne,NULL);/* 密钥长度1024 生成RSA密钥对 */ if(ret != 1) { QMessageBox::information(this,"错误提示","生成RSA密钥错误!无法实现后续数字签名!",QMessageBox::Yes); return; } /* 提取私钥 */ FILE *filename = NULL; filename = fopen("./key/privateKey.pem", "wb"); PEM_write_RSAPrivateKey(filename, rsa, NULL, NULL, 0, NULL, NULL); fclose(filename); filename = NULL; /* 提取公钥 */ unsigned char *n_b = (unsigned char *)calloc(RSA_size(rsa), sizeof(unsigned char)); unsigned char *e_b = (unsigned char *)calloc(RSA_size(rsa), sizeof(unsigned char)); int n_size = BN_bn2bin(rsa->n, n_b); int b_size = BN_bn2bin(rsa->e, e_b); RSA *pubrsa = RSA_new(); pubrsa->n = BN_bin2bn(n_b, n_size, NULL); pubrsa->e = BN_bin2bn(e_b, b_size, NULL);// //另一种格式的公钥输出// filename = fopen("./key/publicKeyRSA.pem", "wb");// PEM_write_RSAPublicKey(filename, pubrsa);// fclose(filename);// filename = NULL; filename = fopen("./key/publicKey.pem", "wb"); PEM_write_RSA_PUBKEY(filename, pubrsa); fclose(filename); filename = NULL; RSA_free(pubrsa); RSA_free(rsa);}
编译链接没有问题,运行发现当执行到PEM_write_RSAPrivateKey时报错:OPENSSL_Uplink(67C97000,08): no OPENSSL_Applink
按照网络上的方法尝试
在main文件中的包含头文件的下方加入OpenSSL的链接头文件(经测试放在在调用的mainwidow.cpp中也可以)
extern "C"{
#include "openssl/applink.c"
};
报错
C:\OpenSSL-Win32\include\openssl\applink.c:-1: In function 'void** OPENSSL_Applink()':
C:\OpenSSL-Win32\include\openssl\applink.c:95: error: invalid conversion from 'void* (*)()' to 'void*' [-fpermissive]
OPENSSL_ApplinkTable[APPLINK_STDIN] = app_stdin;
……
大概是说指针转换出错,全部加上强转,比如
将OPENSSL_ApplinkTable[APPLINK_STDIN] = app_stdin;改为OPENSSL_ApplinkTable[APPLINK_STDIN] =(void*)app_stdin;
编译通过,运行不闪退了
要注意生成公钥和密钥的PEM格式,因为要对应相应的导入函数
-----BEGIN PUBLIC KEY-----MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCfbQTubOxaSqao97+AaS9Esc6FdzZ716bqFUTyhTAKU78yUfaG3GSmPH+HyIZIiZnqlU9Z0MEXhFY6hMgI20ZcuZAAyz6G1hQeaJt1xLSdUblaB5fV6mMPcCuKTgctjq9HJhw47e/iMY+lj+7+30H4Vo43+xLA4RBmUv4M0AXUnQIDAQAB-----END PUBLIC KEY-----
-----BEGIN RSA PRIVATE KEY-----MIICXAIBAAKBgQCfbQTubOxaSqao97+AaS9Esc6FdzZ716bqFUTyhTAKU78yUfaG3GSmPH+HyIZIiZnqlU9Z0MEXhFY6hMgI20ZcuZAAyz6G1hQeaJt1xLSdUblaB5fV6mMPcCuKTgctjq9HJhw47e/iMY+lj+7+30H4Vo43+xLA4RBmUv4M0AXUnQIDAQABAoGBAIHzL03ZY17F8stQBrz5ABqShLCt169ivR+ZbrXwcpQ4Z2TxAm4zP6dxMNLRVQPTha59Pk0LqBkvOcpBaXwuoE6zaILz9xbyWyZzC/zecq4P4NJRGesdo2yTnnhb0dJSOAVydCGuTCbbjS/F4Z854NJ8392+h0XCjwJsV+17apVRAkEAy1A7rG0AyYp2n7b3R0RbDGMbo3Zaxpx2kLHCUOGM6+HLmMuQmff4Y37bsvK27X4IGomptl1+iAJoGGLeM/+7EwJBAMi9S6Uk2xgf9FqQa4BL/SyOkgjntH69LLUstA+69jSb4A/FTKG6R6g09qCARb4MLx6LQwnRA6guE7hma68/948CQGpkbwW4+Nt+iLrlbRsvKxIdXt44ViJuyCDJ1Kysiyj4vKkVhXL8709pmCBZoN5AwI7akSPsYwVbdQul2S+O2F8CQBN8nM1JSKOM5pGsF2N6/PbIWFDY/WKYRrDHyCsGwUPWJegiBRBmHvKrQY3PJfYPBLv4VOetDKfU4UEzYBzBHu0CQDaoJbKyumkQXcZXT5cQ0n8Tu5islB8XeItUqAI3Y9uKZVLTsoTLVAqMyJsEDDIK8AO580NEF++6nzig/LpOvuU=-----END RSA PRIVATE KEY-----
真正使用的时候公钥密钥只需要生成一次,使用密钥生成的签名里面含有不可显示字符,所以如果输出显示要么转为16进制,要么进行base64编码;
提供上面的密钥的鲁123456789的数字签名(十六进制输出),也方便大家对照RSA签名
openssl的RSA数字签名函数RSA_sign没有执行摘要算法,所以要对明文先进行摘要算法SHA1,否则和C# JAVA生成的RSA签名是不一致的!
代码:
void MainWindow::CreateSignature(QByteArray const &strxml,unsigned char *bSign,size_t *iSignlen){ unsigned char *bData = NULL;//报文 bData = (unsigned char*)(strxml.data()); size_t iDatalen = strxml.size(); LoadRSA();//这里可以放在构造函数执行一次加载进来就可以了 unsigned char szTmp[20]={0}; SHA1(bData, iDatalen, szTmp);//一定先生成摘要 int ret = RSA_sign(NID_sha1,szTmp,20,bSign,iSignlen,p_rsa); if(ret!=1) { QMessageBox::information(this,"错误提示","生成签名失败!",QMessageBox::Yes); }}完整的Qt5工程,以及Win32OpenSSL-1_0_2L.exe都上传到CSDN,方便大家参考,欢迎下载评论
参考文献
Windows下openssl的下载安装和使用
openssl之RSA编程
C# RSACryptoServiceProvider加密解密签名验签和DESCryptoServiceProvider加解密
保存openssl中RSA密钥对
SHA1WithRSA签名使用openssl 实现
Qt之OpenSSL
QT添加openssl的方法
openssl编程出现no OPENSSL_Applink
Qt openssl配置,OPENSSL_Applink错误
How to Include OpenSSL in a Qt project
- Qt5使用openssl实现RSA数字签名
- OpenSSL和Python实现RSA Key数字签名和验证
- java使用RSA加密方式,实现数字签名
- 用RSA实现数字签名
- rsa数字签名实现
- 数字签名:RSA-PSS 实现
- 数字签名--RSA实现
- Ubuntu16.04 使用OpenSSL库实现RSA
- openssl 命令行实现数字签名
- openssl RSA java实现
- openssl RSA命令使用
- 使用openssl库实现RSA、AES数据加密
- 使用openssl库实现RSA、AES数据加密
- 使用openssl库实现RSA、AES数据加密
- 使用openssl库实现RSA、AES数据加密
- php使用openssl来实现RSA(非对称加密)
- c++使用openssl库实现RSA、AES数据加密
- 使用openssl库实现RSA、AES数据加密
- Ubuntu 安装R/Rstudio
- Uva 10387 Billiard
- JavaScript闭包实例详解
- JuniperSRX------------用户管理
- Spring学习总结
- Qt5使用openssl实现RSA数字签名
- 在Android开发中使用icon font的代码和方法
- Macaca之测试用例(Node.JS版)
- 3D中的OBJ文件格式详解
- jQuery Validate详解
- Gson-记录一个空格引发的json血案
- Nuttx 之elf 多线程处理
- Solver及其参数配置
- MyBatis框架简介 、MyBatis基本应用