代码
头文件
#ifndef RSA_H
#define RSA_H
#include
#include
#include
#include
#include
// define rsa public key
#define BEGIN_RSA_PUBLIC_KEY "BEGIN RSA PUBLIC KEY" //
#define BEGIN_PUBLIC_KEY "BEGIN PUBLIC KEY" // 公钥头部
#define KEY_LENGTH 1024 // 密钥长度
class rsa
{
public:
rsa();
// 生成一对公钥和私钥
static bool MakeUpRsaKey (QString& publicKey, QString& privateKey);
/**
* @brief rsa_pri_encrypt 私钥加密
* @param strClearData 明文
* @param strPriKey 私钥
* @return 加密后数据(base64格式)
*/
static QString rsa_pri_encrypt_base64 (const QString& strClearData, const QString& strPriKey);
/**
* @brief rsa_pub_decrypt 公钥解密
* @param strDecrypt 待解密数据(base64格式)
* @param strPubKey 公钥钥
* @return 明文
*/
static QString rsa_pub_decrypt_base64 (const QString& strDecryptData, const QString& strPubKey);
/**
* @brief rsa_pub_encrypt 公钥加密
* @param strClearData 明文
* @param strPubKey 私钥
* @return 加密后数据(base64格式)
*/
static QString rsa_pub_encrypt_base64 (const QString& strClearData, const QString& strPubKey);
/**
* @brief rsa_pri_decrypt 私钥解密
* @param strDecrypt 待解密数据(base64格式)
* @param strPriKey 私钥
* @return 明文
*/
static QString rsa_pri_decrypt_base64 (const QString& strDecryptData, const QString& strPriKey);
// 签名 strData 原始字符串; strSigned 签名结果 ; strPriKey 私钥
static bool RSASignAction( char *str, QString &strSigned, const char *pri);
// 验签 strData 原始字符串; strSigned 待验签字符串 ;strPubKey 公钥
static bool RSAVerAction(QString strData,QString &strSigned,QString & strPubKey);
/**< 测试 */
static void test ();
};
#endif // RSA_H
源文件
#include "rsa.h"
// 转换为base64格式输出
int Base64Encode(unsigned char *plaintext, size_t plainlen, char *ciphertext,size_t *cipherlen)
{
if (!ciphertext)
{
*cipherlen = (plainlen + 2) / 3 * 4;
return 0;
}
int nLen = EVP_EncodeBlock((unsigned char *)ciphertext, (const unsigned char *)plaintext,
(int)plainlen);
if (nLen < 0)
{
return -2;
}
*cipherlen = nLen;
return 0;
}
rsa::rsa()
{
}
bool rsa::MakeUpRsaKey (QString& strPubKey, QString& strPriKey)
{
RSA *pRsa = RSA_generate_key(KEY_LENGTH, RSA_3, NULL, NULL);
if ( !pRsa ){
return false;
}
BIO *pPriBio = BIO_new(BIO_s_mem());
PEM_write_bio_RSAPrivateKey(pPriBio, pRsa, NULL, NULL, 0, NULL, NULL);
BIO *pPubBio = BIO_new(BIO_s_mem());
PEM_write_bio_RSAPublicKey(pPubBio, pRsa);
// 获取长度
size_t nPriKeyLen = BIO_pending(pPriBio);
size_t nPubKeyLen = BIO_pending(pPubBio);
// 密钥对读取到字符串
char* pPriKey = new char[nPriKeyLen];
char* pPubKey = new char[nPubKeyLen];
BIO_read(pPriBio, pPriKey, nPriKeyLen);
BIO_read(pPubBio, pPubKey, nPubKeyLen);
// 存储密钥对
strPubKey = QByteArray(pPubKey, nPubKeyLen);
strPriKey = QByteArray(pPriKey, nPriKeyLen);
// 内存释放
RSA_free(pRsa);
BIO_free_all(pPriBio);
BIO_free_all(pPubBio);
delete pPriKey;
delete pPubKey;
return true;
}
/**
* @brief rsa_pri_encrypt 私钥加密
* @param strClearData 明文
* @param strPriKey 私钥
* @return 加密后数据(base64格式)
*/
QString rsa::rsa_pri_encrypt_base64 (const QString& strClearData, const QString& strPriKey)
{
QByteArray priKeyArry = strPriKey.toUtf8();
uchar* pPriKey = (uchar*)priKeyArry.data();
BIO* pKeyBio = BIO_new_mem_buf(pPriKey, strPriKey.length());
if (pKeyBio == NULL){
return "";
}
RSA* pRsa = RSA_new();
pRsa = PEM_read_bio_RSAPrivateKey(pKeyBio, &pRsa, NULL, NULL);
if ( pRsa == NULL ){
BIO_free_all(pKeyBio);
return "";
}
int nLen = RSA_size(pRsa);
char* pEncryptBuf = new char[nLen];
memset(pEncryptBuf, 0, nLen);
QByteArray clearDataArry = strClearData.toUtf8();
int nClearDataLen = clearDataArry.length();
uchar* pClearData = (uchar*)clearDataArry.data();
int nSize = RSA_private_encrypt(nClearDataLen,
pClearData,
(uchar*)pEncryptBuf,
pRsa,
RSA_PKCS1_PADDING);
QString strEncryptData = "";
if ( nSize >= 0 ){
QByteArray arry(pEncryptBuf, nSize);
strEncryptData = arry.toBase64();
}
// 释放内存
delete pEncryptBuf;
BIO_free_all(pKeyBio);
RSA_free(pRsa);
return strEncryptData;
}
/**
* @brief rsa_pub_decrypt 公钥解密
* @param strDecrypt 待解密数据(base64格式)
* @param strPubKey 公钥
* @return 明文
*/
QString rsa::rsa_pub_decrypt_base64(const QString& strDecryptData, const QString& strPubKey)
{
QByteArray pubKeyArry = strPubKey.toUtf8();
uchar* pPubKey = (uchar*)pubKeyArry.data();
BIO* pKeyBio = BIO_new_mem_buf(pPubKey, strPubKey.length());
if (pKeyBio == NULL){
qDebug()<<"error 1";
return "";
}
RSA* pRsa = RSA_new();
if ( strPubKey.contains(BEGIN_RSA_PUBLIC_KEY) ){
pRsa = PEM_read_bio_RSAPublicKey(pKeyBio, &pRsa, NULL, NULL);
}else{
pRsa = PEM_read_bio_RSA_PUBKEY(pKeyBio, &pRsa, NULL, NULL);
}
if ( pRsa == NULL ){
BIO_free_all(pKeyBio);
qDebug()<<"error 2";
return "";
}
int nLen = RSA_size(pRsa);
char* pClearBuf = new char[nLen];
memset(pClearBuf, 0, nLen);
//解密
QByteArray decryptDataArry = strDecryptData.toUtf8();
decryptDataArry = QByteArray::fromBase64(decryptDataArry);
int nDecryptDataLen = decryptDataArry.length();
uchar* pDecryptData = (uchar*)decryptDataArry.data();
int nSize = RSA_public_decrypt(nDecryptDataLen,
pDecryptData,
(uchar*)pClearBuf,
pRsa,
RSA_PKCS1_PADDING);
QString strClearData = "";
if ( nSize >= 0 ){
strClearData = QByteArray(pClearBuf, nSize);
}
// 释放内存
delete pClearBuf;
BIO_free_all(pKeyBio);
RSA_free(pRsa);
return strClearData;
}
/**
* @brief rsa_pub_encrypt 公钥加密
* @param strClearData 明文
* @param strPubKey 私钥
* @return 加密后数据(base64格式)
*/
QString rsa::rsa_pub_encrypt_base64 (const QString& strClearData, const QString& strPubKey)
{
QByteArray pubKeyArry = strPubKey.toUtf8();
uchar* pPubKey = (uchar*)pubKeyArry.data();
BIO* pKeyBio = BIO_new_mem_buf(pPubKey, pubKeyArry.length());
if (pKeyBio == NULL){
return "";
}
RSA* pRsa = RSA_new();
if ( strPubKey.contains(BEGIN_RSA_PUBLIC_KEY) ){
pRsa = PEM_read_bio_RSAPublicKey(pKeyBio, &pRsa, NULL, NULL);
}else{
pRsa = PEM_read_bio_RSA_PUBKEY(pKeyBio, &pRsa, NULL, NULL);
}
if ( pRsa == NULL ){
BIO_free_all(pKeyBio);
return "";
}
int nLen = RSA_size(pRsa);
char* pEncryptBuf = new char[nLen];
memset(pEncryptBuf, 0, nLen);
QByteArray clearDataArry = strClearData.toUtf8();
int nClearDataLen = clearDataArry.length();
uchar* pClearData = (uchar*)clearDataArry.data();
int nSize = RSA_public_encrypt(nClearDataLen,
pClearData,
(uchar*)pEncryptBuf,
pRsa,
RSA_PKCS1_PADDING);
QString strEncryptData = "";
if ( nSize >= 0 ){
QByteArray arry(pEncryptBuf, nSize);
strEncryptData = arry.toBase64();
}
// 释放内存
delete pEncryptBuf;
BIO_free_all(pKeyBio);
RSA_free(pRsa);
return strEncryptData;
}
/**
* @brief rsa_pri_decrypt 私钥解密
* @param strDecrypt 待解密数据(base64格式)
* @param strPriKey 私钥
* @return 明文
*/
QString rsa::rsa_pri_decrypt_base64(const QString& strDecryptData, const QString& strPriKey)
{
QByteArray priKeyArry = strPriKey.toUtf8();
uchar* pPriKey = (uchar*)priKeyArry.data();
BIO* pKeyBio = BIO_new_mem_buf(pPriKey, priKeyArry.length());
if (pKeyBio == NULL){
return "";
}
RSA* pRsa = RSA_new();
pRsa = PEM_read_bio_RSAPrivateKey(pKeyBio, &pRsa, NULL, NULL);
if ( pRsa == NULL ){
BIO_free_all(pKeyBio);
return "";
}
int nLen = RSA_size(pRsa);
char* pClearBuf = new char[nLen];
memset(pClearBuf, 0, nLen);
//解密
QByteArray decryptDataArry = strDecryptData.toUtf8();
decryptDataArry = QByteArray::fromBase64(decryptDataArry);
int nDecryptDataLen = decryptDataArry.length();
uchar* pDecryptData = (uchar*)decryptDataArry.data();
int nSize = RSA_private_decrypt(nDecryptDataLen,
pDecryptData,
(uchar*)pClearBuf,
pRsa,
RSA_PKCS1_PADDING);
QString strClearData = "";
if ( nSize >= 0 ){
strClearData = QByteArray(pClearBuf, nSize);
}
// 释放内存
delete pClearBuf;
BIO_free_all(pKeyBio);
RSA_free(pRsa);
return strClearData;
}
void rsa::test()
{
/**< rsa private/public key 若从文件中拷贝出来,需要注意保存元先文件格式,即换行符需要带上,包括最后一行的换行符 */
//QString strPriKey = "";
// QString strPubKey = "";
/**
* 用代码生成的key与openssl命令生成的key区别:
* 1、代码生成key,标题为 -----BEGIN RSA PUBLIC KEY-----,openssl命令生成key, 标题为 -----BEGIN PUBLIC KEY-----
* 2、获取RSA函数不同,代码生成key,用PEM_read_bio_RSAPublicKey,openssl命令生成key,用PEM_read_bio_RSA_PUBKEY
*/
//MakeUpRsaKey(strPubKey, strPriKey);
//qDebug() << strPubKey << endl;
//qDebug() << strPriKey << endl;
/*strPubKey = QString("-----BEGIN PUBLIC KEY-----\n")+
QString("MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCbXcFx8TIEnRjS9H+KxapUBI6r\n") +
QString("QO8ZeeZKDpa1V/lUg7FsUOdhfjze8YkL2F1et0zSjK7YeQPjWO8NDg7/TTLfpW27\n")+
QString("krhkreYFQ9Y4vHrCKhjc3DD+Yzy9wyKKn5O9M9qU0Kzu8ads/mrPe82/xoo/XDv2\n") +
QString("eTR755MEi1BO+S1RLQIDAQAB\n")+
QString("-----END PUBLIC KEY-----");
strPriKey = QString("-----BEGIN PRIVATE KEY-----\n")+
QString("MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAJtdwXHxMgSdGNL0\n") +
QString("f4rFqlQEjqtA7xl55koOlrVX+VSDsWxQ52F+PN7xiQvYXV63TNKMrth5A+NY7w0O\n") +
QString("Dv9NMt+lbbuSuGSt5gVD1ji8esIqGNzcMP5jPL3DIoqfk70z2pTQrO7xp2z+as97\n") +
QString("zb/Gij9cO/Z5NHvnkwSLUE75LVEtAgMBAAECgYBkwqY9hkaBFX1O+wBoeI9hk98P\n") +
QString("E7q9VABVUSbOjzKFbC855zJYWS2TDSRrSTQsxEYPWuveOoWaAUhvuAlj66YswIL6\n") +
QString("BRgA20eoDr34w+1GABXbFSrP2L1rR2v0qEdiSPsACI0aAmZGO4eq+Fns+EuJ0KSg\n") +
QString("FIZmv3rJV7Nhd9aTQQJBAMmpvcCjxVLfTfiT52j6FDTpAMmd5e832EUEWdzAIzh7\n") +
QString("Z57vsmR7eGbp+9kiRl3eZMOPg2wdfkXvHUrmQK0F/p0CQQDFOpCs75lIVufTZKDU\n") +
QString("7tMQXr4Tzc8EJPaeBuSDXey5okek+ntq55C3xo8nEgDtaVP6mcLqpZR/s+6PjChb\n") +
QString("rk/RAkBzQ7z8pd78Xjx/z3Iec4onL+LOWpz5XW8VC8adQYkgGJECrDjH7DbGhAj6\n") +
QString("c/fKYXowuQ/CNR1etayFihP/kYSVAkB0sxSL3zG5hgKiKHapx66Hjye1HCAT+bMb\n") +
QString("CkUIHflGVelCixufw+jzdL+bhKGb2KjiLT0SDmtxrIvJ0ErJBLkhAkEAj8Yh3H+W\n") +
QString("OWauml/oVqNTbCKttV6irPYVUJkcJnnByjWxVP2I7hmJNuxNAKsNjR204IMsMaWh\n") +
QString("qbByj4ywB5LieQ==\n")+
QString("-----END PRIVATE KEY-----");*/
/* qDebug() << "useing publicKey to Encrypt and privateKey Decrypt:";
QString strClear = "hello334344554 WORLD12W2WDWDEDWDD";
qDebug() << "after publicKey Encrypt:";
QString strEncryptData = rsa_pub_encrypt_base64 (strClear, strPubKey);
qDebug() << strEncryptData;
qDebug()<< "after privateKey Decrypt:";
QString strClearData = rsa_pri_decrypt_base64 (strEncryptData, strPriKey);
qDebug() << strClearData;*/
// 现在进行签名测试,使用私钥签名,公钥验签
QString priKey = QString("-----BEGIN PRIVATE KEY-----\n")+
QString("MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBAJQOMmftEDgwvnM3\n") +
QString("PKWbvF+xvSGLVaJYySSQtmKczEE2ufYR2LM2qwsZhBUwzW+ssKGVrCsjmmI5G4oF\n") +
QString("gcVsa3uA221c6oDaERvQYrFNN9KaLNrIdEA1Nh0MTAg5M6AK2wTHnPH5DGrVXtGs\n") +
QString("k6ZLTuKUjpR8iWMMc+0C5ApG3ssLAgMBAAECgYAEiLbEdf8UKXH7p0plK/LF33SS\n") +
QString("TWkO8rceNoxPUsvyh1GElqFTQ65TRbHE0FzKObijCilenNWCgos0W9zQhfR4pLkJ\n") +
QString("jZyv+W4xJ3qAH7drzcd2MgBP1v91gJK6VPjD+J0pNACF1xGLsFBZmWIbFATDU38z\n") +
QString("3SbTPVS15oPXgDdEwQJBAOF2v+skafKdtKmLgy3Hna+iA+uNNUZ7q8bQyjY4nviV\n") +
QString("FRL3MBgugIpUYaiiCzhl8BZftoB6pg0DCBOlQxONgiECQQCoG43bGjM0uh7e8cMT\n") +
QString("45OJDruii7wQnpJuZZH67qOGtnZA/coYDGArqFwmrQz2nQJGwePvNt4kT3Ibighf\n") +
QString("ev+rAkEAtuXKEkpb2ACvCcqvA3gnJs7bNz45tY+lbYb6Qrnz29u0WMpFLZirlYuW\n") +
QString("HWI2j+3BsaS7O8ZC5dNLvgQWQcpNgQJBAJwm3CIFuELmD/7ve1FiN408TjayrcKS\n") +
QString("SVqapnr8aJGds0Kze6HS/RIQlWinnj8FoTOwrtVplfcMhOXn1dc7HXkCQQCRu9UN\n") +
QString("4mMrQLLg7S88fbjxsy7+cuELxBNrix3GU8F6EAtWWq2e1EaUu0VVtRq7f/IKPdKD\n") +
QString("uEBxsPfr/EXy6yDw\n")+
QString("-----END PRIVATE KEY-----");
QString pbKey = QString("-----BEGIN PUBLIC KEY-----\n")+
QString("MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCUDjJn7RA4ML5zNzylm7xfsb0h\n") +
QString("i1WiWMkkkLZinMxBNrn2EdizNqsLGYQVMM1vrLChlawrI5piORuKBYHFbGt7gNtt\n")+
QString("XOqA2hEb0GKxTTfSmizayHRANTYdDEwIOTOgCtsEx5zx+Qxq1V7RrJOmS07ilI6U\n") +
QString("fIljDHPtAuQKRt7LCwIDAQAB\n")+
QString("-----END PUBLIC KEY-----");
QString aaa = "SZHAILEI88123456&111122334";
QString ret="";
rsa::RSASignAction(aaa,ret,priKey);
qDebug()<<"after =========> "<<ret;
bool flag = rsa::RSAVerAction(aaa,ret,pbKey);
if(flag){
qDebug()<<"@@@@@@@@@@ success !";
}else{
qDebug()<<"@@@@@@@@@ failed !";
}
}
bool rsa::RSASignAction(QString strData, QString &strSigned,QString &strPriKey)
{
qDebug()<<"now rsa sign";
QByteArray clearDataArry = strData.toUtf8();
int len = clearDataArry.length();
QByteArray priKeyArry = strPriKey.toUtf8();
uchar* pPriKey = (uchar*)priKeyArry.data();
BIO* pKeyBio = BIO_new_mem_buf(pPriKey, strPriKey.length());
if (pKeyBio == NULL){
return false;
}
RSA* prsa = NULL;
prsa = PEM_read_bio_RSAPrivateKey(pKeyBio, &prsa, NULL, NULL);
if ( prsa == NULL ){
BIO_free_all(pKeyBio);
return false;
}
unsigned char szTmp[1024] = {0};
SHA256((const unsigned char*)clearDataArry.data(),len,szTmp);
int nlen = 0;
unsigned int nlenRet = 0;
char szTmp1[1024] = {0};
nlen = RSA_sign(NID_sha256,szTmp,SHA256_DIGEST_LENGTH,(unsigned char*)szTmp1,&nlenRet,prsa);
if(nlen!=1){
RSA_free(prsa);
BIO_free_all(pKeyBio);
return false;
}
QByteArray arry = QByteArray(szTmp1);
strSigned = QString(arry.toBase64());
BIO_free_all(pKeyBio);
RSA_free(prsa);
return true;
}
bool rsa::RSAVerAction( char *str, QString &strSigned, const char *pri)
{
int len = strlen(str);
BIO* pKeyBio = BIO_new_mem_buf(pri, strlen(pri));
if (pKeyBio == NULL){
return false;
}
RSA* prsa = NULL;
prsa = PEM_read_bio_RSAPrivateKey(pKeyBio, &prsa, NULL, NULL);
if ( prsa == NULL ){
BIO_free_all(pKeyBio);
return false;
}
unsigned char szTmp[1024] = {0};
SHA256((const unsigned char*)str,len,szTmp);
int nlen = 0;
unsigned int nlenRet = 0;
unsigned char szTmp1[1024] = {0};
nlen = RSA_sign(NID_sha256,szTmp,SHA256_DIGEST_LENGTH,szTmp1,&nlenRet,prsa);
if(nlen!=1){
RSA_free(prsa);
BIO_free_all(pKeyBio);
return false;
}
size_t plainlen = 0;
uint8_t plaintext[1024]={0};
Base64Encode(szTmp1,nlenRet,(char*)plaintext,&plainlen);
strSigned = QString("%1").arg((char*)plaintext);
BIO_free_all(pKeyBio);
RSA_free(prsa);
return true;
}