#include <iostream>
#include <sstream>
#include "rsa.h"
#include "bn.h"
#include "cp_api.h"
#include "RSAcrypter.h"
#include "base64.h"
#define param(name, sep) \
#name "=" << name << sep
#define save(store, value) \
std::istringstream exchanger(value); \
exchanger >> store;
#define parse_var(name, value, var) \
if(std::string(name) == #var ) { \
save(var, value) \
}
#define DELETE(p) if (p) {delete p; p = NULL;}
char *STRNCPY(char *dest, const char *src, size_t n)
{
strncpy(dest, src, n);
if (strlen(src) >= n)
dest[n] = '\0';
return dest;
}
void escape(const char* const src, char* dst, int size, char sep = '&')
{
std::string str = src;
char escape[4];
memset(escape, 0, sizeof(escape));
for(unsigned int i = 0; i < str.length(); )
{
switch(str[i])
{
case '&' :
case '%' :
case '=' :
case '\r' :
case '\n' :
sprintf(escape, "%%%02x", str[i]);
str.replace(i, 1, escape);
i += 3;
break;
default :
if (str[i] == sep)
{
// 特殊字符
sprintf(escape, "%%%02x", str[i]);
str.replace(i, 1, escape);
i += 3;
continue;
}
i++;
}
}
strncpy(dst, str.c_str(), size);
return;
}
char Hex2Char(char *what)
{
std::string hex2int = "0123456789ABCDEF";
return (char)(hex2int.find(toupper(what[0])) * 16 + hex2int.find(toupper(what[1])));
}
void unescape(char *url)
{
register int x,y;
for (x=0, y=0; url[y]; ++x, ++y)
{
if((url[x] = url[y]) == '%')
{
url[x] = Hex2Char(&url[y + 1]);
y += 2;
}
}
url[x] = '\0';
return;
}
static
// type = 1, 读取的是公钥
// type = 2, 读取的私钥
int readKey(const char *const key, int iLen, int type, RSA* rsa)
{
unsigned dsize = 0;
unsigned char *ptrBuff = NULL;
const char *p = key;
int iTmpLen = iLen;
//读取e
if (iTmpLen < 4) return -1;
memcpy(&dsize, p, 4);
p += 4;
iTmpLen -= 4;
if (dsize < 0 || dsize > 4096) return -2;
ptrBuff = (unsigned char*)new char[dsize];
if (ptrBuff == NULL) return -3;
if (iTmpLen < (int)dsize) return -4;
memcpy(ptrBuff, p, dsize);
p += dsize;
iTmpLen -= dsize;
rsa->e = BN_bin2bn(ptrBuff, dsize, rsa->e);
delete []ptrBuff;
ptrBuff = NULL;
//读取key
if (iTmpLen < 4) return -5;
memcpy(&dsize, p, 4);
p+= 4;
iTmpLen -= 4;
if (dsize < 0 || dsize > 4096) return -6;
ptrBuff = (unsigned char*)new char[dsize];
if (ptrBuff == NULL) return -7;
if (iTmpLen < (int)dsize) return -8;
memcpy(ptrBuff, p, dsize);
if (type == 1)
rsa->n = BN_bin2bn(ptrBuff, dsize, rsa->n);
else if (type == 2)
rsa->d = BN_bin2bn(ptrBuff , dsize, rsa->d);
else return -9;
return 0;
}
static //从字符串读取rsa结构(字符串里存的是二进制结构)
int ReadRSAStructFromString(const char* const public_key, int iPublicLen,
const char* const private_key, int iPrivateLen, unsigned char* key)
{
RSA* rsa = (RSA*)key;
if (public_key == NULL && private_key == NULL)
return 1;
if (rsa == NULL)
return 1;
int iRet;
if (public_key != NULL)
{
if ((iRet = readKey(public_key, iPublicLen, 1, rsa)) != 0)
return iRet;
}
if (private_key != NULL)
{
if ((iRet = readKey(private_key, iPrivateLen, 2, rsa)) != 0)
return iRet;
}
return 0;
}
int BNet::HttpRequest::genRsaSignature(
const char* dataToEncrypt, const char* privateKey, const char* publicKey, RsaKey* rsaSignature)
{
// 生成新的rsa 实例
QPAYRKey *key = QPAYRKey_new();
if (key == NULL)
return -1;
struct Tmpbuff{
unsigned char value[MAX_BNET_BUFF_LEN + 1];
int len;
};
Tmpbuff privateKeyBuff = {{0},0};
Tmpbuff publicKeyBuff = {{0},0};
Base64_Decode(publicKey, strlen(publicKey), (unsigned char*)publicKeyBuff.value, sizeof(publicKeyBuff.value)-1, &publicKeyBuff.len);
Base64_Decode(privateKey, strlen(privateKey), (unsigned char*)privateKeyBuff.value, sizeof(privateKeyBuff.value)-1, &privateKeyBuff.len);
int status = ReadRSAStructFromString((char*)publicKeyBuff.value, publicKeyBuff.len, (char*)privateKeyBuff.value, privateKeyBuff.len, key);
if (status != 0)
return -1;
Crypter::buffer* pstBuffer = NULL;
RSAcrypter coRSAcrypter(key);
// 签名
memset(rsaSignature->value, 0, sizeof(rsaSignature->value));
char szTmpBuf3[MAX_BNET_BUFF_LEN + 1] = {0};
pstBuffer = coRSAcrypter.private_sign((unsigned char*)dataToEncrypt, strlen(dataToEncrypt));
if (pstBuffer != NULL) { //成功
Base64_Encode(pstBuffer->data, pstBuffer->len, szTmpBuf3, MAX_BNET_BUFF_LEN, &publicKeyBuff.len);
}
else
return -1;
escape(szTmpBuf3, rsaSignature->value, sizeof(rsaSignature->value) - 1);
DELETE(pstBuffer);
QPAYRKey_free(key);
return 0;
}
BNet::HttpResponse::HttpResponse(const std::string& urlParams): _urlParams(urlParams)
{
}
int BNet::HttpResponse::verifyRsaSignature(const char* publicKey)
{
char szTrueKey[MAX_BNET_BUFF_LEN + 1] = {0};
STRNCPY (szTrueKey, getRsaSignature().c_str(), MAX_BNET_BUFF_LEN);
unescape(szTrueKey);
QPAYRKey *key = QPAYRKey_new(); // 生成新的rsa 实例
if (key == NULL)
return -1;
struct {
unsigned char value[MAX_BNET_BUFF_LEN + 1];
int len;
}tmpBuff = {{0},0};
// 读取rsa 结构
Base64_Decode(publicKey, strlen(publicKey), tmpBuff.value, sizeof(tmpBuff.value)-1, &tmpBuff.len);
int status = ReadRSAStructFromString((char *)tmpBuff.value, tmpBuff.len, NULL, 0, key);
if (status != 0)
return -1;
RSAcrypter coRSAcrypter(key);
// unpt verifydata
memset(tmpBuff.value, 0, sizeof(tmpBuff.value));
Base64_Decode(szTrueKey, strlen(szTrueKey), (unsigned char*)tmpBuff.value, sizeof(tmpBuff.value)-1, &tmpBuff.len);
// 验签
status = coRSAcrypter.public_verify((unsigned char*)getUrlParamsStrWithoutRsakey().c_str(), getUrlParamsStrWithoutRsakey().length(), tmpBuff.value, tmpBuff.len);
QPAYRKey_free(key);
return status;
}
BNet::HttpResponseStatus::HttpResponseStatus() {
ret_code = 0;
err_msg = "";
key = "";
}
/////////////////////////////////////////////////////////////////////
// 包月(包时段)定购接口
std::string BNet::TimesliceOrderRequest::getUrlParamsStrWithRsakey(std::string& privateKey, std::string& publicKey)
{
std::ostringstream urlParams;
urlParams
<< param(cpid,"&")
<< param(service_id,"&")
<< param(user_id,"&")
<< param(user_type,"&")
<< param(pay_type,"&")
<< param(fee_type,"&")
<< param(days,"&")
<< param(source,"&")
<< param(from,"&")
<< param(time,"&")
<< param(ret_url,"&")
<< param(ret_para,"");
RsaKey _rsaSignature;
std::string _urlParams = urlParams.str();
genRsaSignature(_urlParams.c_str(), privateKey.c_str(), publicKey.c_str(), &_rsaSignature);
//为了避免参数被编码后不能正确验签,在签名之后加上escape操作。
char Escaped_Buffer[MAX_BNET_BUFF_LEN+1]={0};
escape(ret_para.c_str(), Escaped_Buffer, sizeof(Escaped_Buffer));
ret_para=std::string(Escaped_Buffer);
std::ostringstream urlParams2;
urlParams2
<< param(cpid,"&")
<< param(service_id,"&")
<< param(user_id,"&")
<< param(user_type,"&")
<< param(pay_type,"&")
<< param(fee_type,"&")
<< param(days,"&")
<< param(source,"&")
<< param(from,"&")
<< param(time,"&")
<< param(ret_url,"&")
<< param(ret_para,"");
urlParams2 << "&key=" << _rsaSignature.value;
return urlParams2.str();
}
BNet::TimesliceOrderResponse::TimesliceOrderResponse(const std::string& urlParams): HttpResponse(urlParams)
{
}
void BNet::TimesliceOrderResponse::parseUrlParams()
{
std::istringstream urlParams(_urlParams);
char line[MAX_BNET_BUFF_LEN];
while( urlParams.getli
基于PHP的仿青帝文学网整站php版v1.7源码.zip
版权申诉
14 浏览量
2023-10-10
21:16:28
上传
评论
收藏 11.1MB ZIP 举报
![avatar](https://profile-avatar.csdnimg.cn/ace77722cc904668be9c7ee0feb247ba_dwf1354046363.jpg!1)
![avatar-vip](https://csdnimg.cn/release/downloadcmsfe/public/img/user-vip.1c89f3c5.png)
易小侠
- 粉丝: 6508
- 资源: 9万+
最新资源
- Installing Anaconda and PyCharm - Marco Sammon
- git使用文档(一步一步教你使用Git仓库管理代码)
- 进制转换(通用版).cpp
- linux实践之从DistroWatch排名第三的EndeavourOS转到排名第五的Manjaro工作机迁移
- Discuz模板+资讯博客课程干货+商业版(GBK+UTF)
- 基于Selenium的Java爬虫实战(内含谷歌浏览器Chrom和Chromedriver版本123.0.6292.0)
- RB308A-SOT23-5 单节锂电池保护IC 深圳市可芯电子有限公司.pdf
- Ubuntu下安装JDK
- 基于Selenium的Java爬虫实战(内含谷歌浏览器Chrom和Chromedriver版本123.0.6291.0)
- Android基础之用Eclipse建立工程
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
![feedback](https://img-home.csdnimg.cn/images/20220527035711.png)
![feedback](https://img-home.csdnimg.cn/images/20220527035711.png)
![feedback-tip](https://img-home.csdnimg.cn/images/20220527035111.png)