1977年,三位数学家Rivest、Shamir 和 Adleman 设计了一种算法,可以实现非对称加密。这种算法用他们三个人的名字命名,叫做RSA算法。从那时直到现在,RSA算法一直是最广为使用的"非对称加密算法"。毫不夸张地说,只要有计算机网络的地方,就有RSA算法。这种算法非常可靠,密钥越长,它就越难破解。根据已经披露的文献,目前被破解的最长RSA密钥是232个十进制位,也就是768个二进制位,因此可以认为,1024位的RSA密钥基本安全,2048位的密钥极其安全,当然量子计算机除外。
以下下方法实现了非对称加密算法Rsa c++的加解密和java的加解密,可以在jni过程中提高安全性,代码中的公钥和私钥建议从文件获取,不以明文的方式放在本地,方法不予赘述
//
// RsaUtil.cpp
//
// C++加密和解密过程
//
// Created by Versprechen on 2023/9/14.
//#include <iostream>
#include "RsaUtil.hpp"#if CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID
#include "openssl/rsa.h"
#include "openssl/pem.h"
#include "openssl/err.h"
#include "openssl/evp.h"
#endif#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "JniTools.h"
#include "Base64Util.hpp"RsaUtil::RsaUtil()
{
}RsaUtil::~RsaUtil()
{
}
RsaUtil *RsaUtil::m_instance = nullptr;
RsaUtil *RsaUtil::getInstance()
{if (nullptr == m_instance){m_instance = new RsaUtil;}return m_instance;
}void RsaUtil::release()
{if (m_instance){}CC_SAFE_DELETE(m_instance);
}void RsaUtil::initKey()
{m_privateKey = Base64Util::getInstance()->base64_decode(m_privateKey);m_publicKey = Base64Util::getInstance()->base64_decode(m_publicKey);
}/** 非对称加密算法Rsa工具类的使用:* 双方加密解密遵循 PKCS#8 公钥和私钥格式* 1、createKey:创建公钥和私钥* 加密前需要保证公钥格式以"-----BEGIN RSA PUBLIC KEY-----"开头,以"-----END RSA PUBLIC KEY-----"结尾* 私钥以"-----BEGIN RSA PRIVATE KEY-----"开头* 2、RSAEncrypt加密,加密之后会使用base64_encode加密,防止传输错误* 3、RSADecrypt解密,解密流程是先把传回来的字符串base64_decode解密,再走加密算法** 注意:使用Jni交互的数据需要先使用base64加密/解密*/// 创建rsa的私钥和公钥,覆盖成员变量
void RsaUtil::createKeys()
{
#if CC_TARGET_PLATFORM == CC_PLATFORM_ANDROIDRSA *rsa = RSA_new();BIGNUM *e = BN_new();BN_set_word(e, RSA_F4);RSA_generate_key_ex(rsa, 2048, e, NULL);BIO *publicBIO = BIO_new(BIO_s_mem());PEM_write_bio_RSA_PUBKEY(publicBIO, rsa);BIO *privateBIO = BIO_new(BIO_s_mem());EVP_PKEY *pkey = EVP_PKEY_new();EVP_PKEY_assign_RSA(pkey, rsa); // rsa will be freed when pkey is freedPEM_write_bio_PKCS8PrivateKey(privateBIO, pkey, NULL, NULL, 0, NULL, NULL);char *publicKey;long publicKeyLength = BIO_get_mem_data(publicBIO, &publicKey);char *privateKey;long privateKeyLength = BIO_get_mem_data(privateBIO, &privateKey);m_publicKey = std::string(publicKey, publicKeyLength);m_privateKey = std::string(privateKey, privateKeyLength);m_publicKey = removeKeyHeaderAndFooter(m_publicKey);m_privateKey = removeKeyHeaderAndFooter(m_privateKey);NXLOG("公钥:%s", m_publicKey.c_str());NXLOG("私钥:%s", m_privateKey.c_str());BN_free(e);BIO_free(publicBIO);BIO_free(privateBIO);EVP_PKEY_free(pkey);
#endif
}// 由于java需要去掉头尾标记符,生成之后需要去掉给他们
std::string RsaUtil::removeKeyHeaderAndFooter(const std::string &key)
{std::string result = key;std::string header1 = "-----BEGIN RSA PUBLIC KEY-----";std::string header2 = "-----BEGIN RSA PRIVATE KEY-----";std::string footer = "-----END RSA PUBLIC KEY-----";size_t pos;while ((pos = result.find(header1)) != std::string::ase(pos, header1.length());while ((pos = result.find(header2)) != std::string::ase(pos, header2.length());while ((pos = result.find(footer)) != std::string::ase(pos, footer.length());return result;
}// 加密函数
std::string RsaUtil::RSAEncrypt(std::string plainText)
{
#if CC_TARGET_PLATFORM == CC_PLATFORM_ANDROIDBIO *keybio = BIO_new_mem_buf(m_publicKey.c_str(), -1);RSA *rsa = PEM_read_bio_RSA_PUBKEY(keybio, NULL, NULL, NULL); // 修改这里std::string encryptedData(RSA_size(rsa), '