- 新增ISV用户平台

- 新增门户网站(portal)
- 新增`C++`,`Rust`语言SDK
This commit is contained in:
tanghc
2020-11-07 10:55:12 +08:00
parent 1370883af9
commit 6ab696dfaf
599 changed files with 34834 additions and 141 deletions

View File

@@ -0,0 +1,133 @@
#include "OpenClient.h"
#include "httplib.h"
#include "tool.h"
#include "sign.h"
#include "../thirdparty/CJsonObject/CJsonObject.hpp"
httplib::Headers headers = {
{"Accept-Encoding", "identity"}
};
const string ERROR_NODE = "error_response";
OpenClient::OpenClient(const string &appId, const string &privateKeyFilePath, const string &url) {
this->appId = appId;
this->privateKeyFilePath = privateKeyFilePath;
char *_url = const_cast<char *>(url.c_str());
char *host;
int port;
char *path;
tool::parse_url(_url, &host, &port, &path);
this->hostInfo = HostInfo{
host = host,
port = port,
path = path
};
}
neb::CJsonObject OpenClient::execute(BaseRequest *request) {
return this->execute(request, "");
}
neb::CJsonObject OpenClient::execute(BaseRequest *request, const string &token) {
string method = request->getMethod();
string version = request->getVersion();
RequestType requestType = request->getRequestType();
map<string, string> bizModel = request->bizModel;
// 创建HTTP请求客户端
httplib::Client cli(this->hostInfo.host, this->hostInfo.port);
// 构建请求参数
map<string, string> allParams = this->buildParams(request, token);
char *path = this->hostInfo.path;
string responseBody;
// 如果有文件上传
if (!request->getFiles().empty()) {
httplib::MultipartFormDataItems items = OpenClient::getMultipartFormDataItems(
allParams, request->getFiles());
responseBody = cli.Post(path, headers, items)->body;
} else {
switch (requestType) {
case GET: {
responseBody = cli.Get(path, allParams, headers)->body;
break;
}
case POST_FORM: {
responseBody = cli.Post(path, headers, OpenClient::getParams(allParams))->body;
break;
}
case POST_JSON: {
string json = tool::mapToJson(allParams);
responseBody = cli.Post(path, json, "application/json")->body;
break;
}
case POST_FILE: {
httplib::MultipartFormDataItems items = OpenClient::getMultipartFormDataItems(
allParams, request->getFiles());
responseBody = cli.Post(path, headers, items)->body;
}
}
}
return OpenClient::parseResponse(responseBody, request);
}
httplib::Params OpenClient::getParams(map<string, string> allParams) {
httplib::Params params;
map<string, string>::iterator it;
for (it = allParams.begin(); it != allParams.end(); ++it) {
params.emplace(it->first, it->second);
}
return params;
}
map<string, string> OpenClient::buildParams(BaseRequest *request, const string &token) {
map<string, string> allParams;
allParams["app_id"] = this->appId;
allParams["method"] = request->getMethod();
allParams["charset"] = "UTF-8";
allParams["sign_type"] = "RSA2";
allParams["timestamp"] = tool::getTime();
allParams["version"] = request->getVersion();
if (!token.empty()) {
allParams["app_auth_token"] = token;
}
map<string, string> bizModel = request->bizModel;
allParams.insert(bizModel.begin(), bizModel.end());
// 生成签名
string sign = signutil::createSign(allParams, this->privateKeyFilePath, "RSA2");
allParams["sign"] = sign;
return allParams;
}
httplib::MultipartFormDataItems
OpenClient::getMultipartFormDataItems(map<string, string> allParams, vector<FileInfo> fileInfoList) {
httplib::MultipartFormDataItems items = {};
map<string, string>::iterator it;
for (it = allParams.begin(); it != allParams.end(); ++it) {
items.push_back({it->first, it->second, "", ""});
}
// 添加上传文件
vector<FileInfo>::iterator vit;
for (vit = fileInfoList.begin(); vit != fileInfoList.end(); vit++) {
string content = tool::getFileContent(vit->filepath);
items.push_back({vit->name, content, tool::getFilename(vit->filepath), "application/octet-stream"});
}
return items;
}
neb::CJsonObject OpenClient::parseResponse(const string& responseBody, BaseRequest *request) {
neb::CJsonObject oJson(responseBody);
neb::CJsonObject data = oJson[ERROR_NODE];
if (data.IsEmpty()) {
string method = request->getMethod();
string nodeName = tool::replace(method.c_str(),".","_") + "_response";
data = oJson[nodeName];
}
return data;
}

View File

@@ -0,0 +1,66 @@
#ifndef SDK_CXX_OPENCLIENT_H
#define SDK_CXX_OPENCLIENT_H
#include <string>
#include "httplib.h"
#include "../request/BaseRequest.h"
#include "../thirdparty/CJsonObject/CJsonObject.hpp"
using namespace std;
struct HostInfo {
string host;
int port;
char *path;
};
/**
* 请求客户端
*/
class OpenClient {
private:
/** 应用id */
string appId;
/** 私钥文件路径 */
string privateKeyFilePath;
public:
/**
* 创建客户端对象
* @param appId 应用ID
* @param privateKeyFilePath 应用私钥路径
* @param url 请求URL
*/
OpenClient(const string &appId, const string &privateKeyFilePath, const string &url);
/**
* 发送请求
* @param request 请求对象BaseRequest的子类
* @param token token
* @return 返回响应结果
*/
neb::CJsonObject execute(BaseRequest *request, const string& token);
/**
* 发送请求
* @param request 请求对象BaseRequest的子类
* @return 返回响应结果
*/
neb::CJsonObject execute(BaseRequest *request);
private:
HostInfo hostInfo;
map<string, string> buildParams(BaseRequest *request, const string& token);
static httplib::MultipartFormDataItems
getMultipartFormDataItems(map<string, string> allParams, vector<FileInfo> fileInfoList);
static httplib::Params getParams(map<string, string> params);
static neb::CJsonObject parseResponse(const string& responseBody,BaseRequest *request);
};
#endif //SDK_CXX_OPENCLIENT_H

View File

@@ -0,0 +1,94 @@
#include "stdafx.h"
#include "RSASign.h"
#include "../thirdparty/base64/base64.h"
RSA* GetPublicKeyEx(char* szPath)
{
RSA *pubkey = RSA_new();
BIO *pubio;
pubio = BIO_new_file(szPath, "rb");
pubkey = PEM_read_bio_RSAPublicKey(pubio, &pubkey, NULL, NULL);
BIO_free(pubio);
return pubkey;
}
RSA* GetPrivateKeyEx(char* szPath)
{
RSA *prikey = RSA_new();
BIO *priio;
priio = BIO_new_file(szPath, "rb");
prikey = PEM_read_bio_RSAPrivateKey(priio, &prikey, NULL, NULL);
BIO_free(priio);
return prikey;
}
bool RSASignAction(const string& strEnData, char *privateKeyFilePath, string &strSigned)
{
int nlen = strEnData.length();
RSA *prsa = NULL;
if (NULL == (prsa = GetPrivateKeyEx(privateKeyFilePath)))
{
RSA_free(prsa);
printf("获取私钥失败\n");
return false;
}
char szTmp[1024] = { 0 };
//对待签名数据做SHA1摘要
SHA256((const unsigned char*)strEnData.c_str(), nlen, (unsigned char*)szTmp);
int nLength;
unsigned int nLengthRet;
char szTmp1[1024] = { 0 }; //位数一定不能小于等于RSA的128位没有\0,数据会增加后面位数
// unsigned char *szTmp1 = {0};
nLength = RSA_sign(NID_sha256, (unsigned char *)szTmp, 32, (unsigned char *)szTmp1, &nLengthRet, prsa);
if (nLength != 1)
{
RSA_free(prsa);
return false;
}
strSigned = base64_encode((unsigned char *)szTmp1, strlen((const char *)szTmp1));
RSA_free(prsa);
return true;
}
bool RSAVerifyAction(string strEnData, string &strSigned)
{
int nlen = strEnData.length();
printf("验签的原始数据:[%s]\n", strEnData.c_str());
RSA *prsa = NULL;
if (NULL == (prsa = GetPublicKeyEx(PUBLIC_KEY_FILE_EX)))
{
RSA_free(prsa);
printf("获取公钥失败\n");
return -1;
}
//对待签名数据做SHA1摘要
char szTmp[1024] = { 0 };
int nLen = strEnData.length();
SHA256((const unsigned char*)strEnData.c_str(), nLen, (unsigned char*)szTmp);
int nLength;
unsigned int nLengthRet = strSigned.length();
printf("nLengthRet2 = %d\n", nLengthRet);
nLength = RSA_verify(NID_sha256, (unsigned char *)szTmp, 32, (unsigned char*)strSigned.c_str(), nLengthRet, prsa);
if (nLength != 1)
{
RSA_free(prsa);
return false;
}
RSA_free(prsa);
return true;
}

View File

@@ -0,0 +1,19 @@
#pragma once
#include <openssl/objects.h>
#include <openssl/rsa.h>
#include <openssl/pem.h>
#include <openssl/bio.h>
#include <openssl/err.h>
#include <string>
using namespace std;
#define PUBLIC_KEY_FILE_EX "publicEx.pem" //公钥文件
#define PRIVATE_KEY_FILE_EX "privateEx.pem" //私钥文件
RSA* GetPublicKeyEx(char* szPath);
RSA* GetPrivateKeyEx(char* szPath);
bool RSASignAction(const string& strEnData,char *privateKeyFilePath, string &strSigned);
bool RSAVerifyAction(string strEnData, string &strSigned);

View File

@@ -0,0 +1,11 @@
#ifndef SDK_CXX_REQUESTTYPE_H
#define SDK_CXX_REQUESTTYPE_H
enum RequestType {
GET,
POST_FORM,
POST_JSON,
POST_FILE
};
#endif //SDK_CXX_REQUESTTYPE_H

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,270 @@
/*
* Filename: sha256.cpp
* Author: L.Y.
* Brief: SHA256算法实现
* Version: V1.0.0
* Update log:
* 120191108-20191113 V1.0.0
* 1、初次版本。
* TODO:
* Attention:
* 1输入信息中有中文时得到的数字指纹与使用SHA256在线加密工具得到数字指纹可能不相同。
* 原因是中文的编码方式不同。
*/
#include "sha256.hpp"
#include <iomanip>
#include <sstream>
#include <string>
#include <vector>
namespace digest
{
//////////////////////////////// 静态数据成员初始化 //////////////////////////////////////////
std::vector<uint32_t> Sha256::initial_message_digest_ =
{
0x6a09e667, 0xbb67ae85, 0x3c6ef372,
0xa54ff53a, 0x510e527f, 0x9b05688c,
0x1f83d9ab, 0x5be0cd19
};
std::vector<uint32_t> Sha256::add_constant_ =
{
0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5,0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5,
0xd807aa98,0x12835b01,0x243185be,0x550c7dc3,0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174,
0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc,0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da,
0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7,0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967,
0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13,0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85,
0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3,0xd192e819,0xd6990624,0xf40e3585,0x106aa070,
0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5,0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3,
0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208,0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2
};
//////////////////////////////// 成员函数的定义 //////////////////////////////////////////
bool Sha256::encrypt(const std::vector<uint8_t>& input_message,
std::vector<uint8_t>* _digest)
{
if (!input_message.empty() && _digest)
{
//! 文本预处理
std::vector<uint8_t> message = input_message;
preprocessing(&message);
//! 将文本分解成连续的64Byte大小的数据块
std::vector<std::vector<uint8_t>> chunks;
breakTextInto64ByteChunks(message, &chunks);
//! 由64Byte大小的数据块构造出64个4Byte大小的字。然后进行循环迭代。
std::vector<uint32_t> message_digest(initial_message_digest_); // 初始化信息摘要
std::vector<uint32_t> words;
for (const auto& chunk : chunks)
{
structureWords(chunk, &words);
transform(words, &message_digest);
}
//! 获取最终结果
produceFinalHashValue(message_digest, _digest);
return true;
}
else
{
return false;
}
}
std::string Sha256::getHexMessageDigest(const std::string& message)
{
if (!message.empty())
{
std::vector<uint8_t> __message;
for (auto it = message.begin(); it != message.end(); ++it)
{
__message.push_back(static_cast<uint8_t>(*it));
}
std::vector<uint8_t> digest;
encrypt(__message, &digest);
std::ostringstream o_s;
o_s << std::hex << std::setiosflags(std::ios::uppercase);
for (auto it = digest.begin(); it != digest.end(); ++it)
{
o_s << std::setw(2) << std::setfill('0')
<< static_cast<unsigned short>(*it);
}
return o_s.str();
}
else
{
return "";
}
}
bool Sha256::preprocessing(std::vector<uint8_t>* _message) const
{
if (_message)
{
const uint64_t original_bit_size = _message->size() * 8;
//! 附加填充比特
size_t remainder = _message->size() % 64;
if (remainder < 56)
{
_message->push_back(0x80); // ox80 == 10000000
for (size_t i = 1; i < 56 - remainder; ++i)
{
_message->push_back(0x00);
}
}
else if (remainder == 56)
{
_message->push_back(0x80);
for (size_t i = 1; i < 64; ++i)
{
_message->push_back(0x00);
}
}
else
{
_message->push_back(0x80);
for (size_t i = 1; i < 64 - remainder + 56; ++i)
{
_message->push_back(0x00);
}
}
//! 附加原始文本的长度值
for (int i = 1; i <= 8; ++i)
{
uint8_t c = static_cast<uint8_t>(original_bit_size >> (64 - 8 * i));
_message->push_back(c);
}
return true;
}
else
{
return false;
}
}
bool Sha256::breakTextInto64ByteChunks(const std::vector<uint8_t>& message,
std::vector<std::vector<uint8_t>>* _chunks) const
{
if (_chunks && 0 == message.size() % 64)
{
_chunks->clear(); // 清空输出buffer
size_t quotient = message.size() / 64;
for (size_t i = 0; i < quotient; ++i)
{
std::vector<uint8_t> temp(message.begin() + i * 64, message.begin() + (i + 1) * 64);
_chunks->push_back(temp);
}
return true;
}
else
{
return false;
}
}
bool Sha256::structureWords(const std::vector<uint8_t>& chunk,
std::vector<uint32_t>* _words) const
{
if (_words && 64 == chunk.size())
{
_words->resize(64);
auto& words = *_words;
for (int i = 0; i < 16; ++i)
{
words[i] = (static_cast<uint32_t>(chunk[i * 4]) << 24)
| (static_cast<uint32_t>(chunk[i * 4 + 1]) << 16)
| (static_cast<uint32_t>(chunk[i * 4 + 2]) << 8)
| static_cast<uint32_t>(chunk[i * 4 + 3]);
}
for (int i = 16; i < 64; ++i)
{
words[i] = small_sigma1(words[i - 2])
+ words[i - 7]
+ small_sigma0(words[i - 15])
+ words[i - 16];
}
return true;
}
else
{
return false;
}
}
bool Sha256::transform(const std::vector<uint32_t>& words,
std::vector<uint32_t>* _message_digest) const
{
if (_message_digest && 8 == _message_digest->size() && 64 == words.size())
{
std::vector<uint32_t> d = *_message_digest;
for (int i = 0; i < 64; ++i)
{
uint32_t temp1 = d[7] + big_sigma1(d[4]) + ch(d[4], d[5], d[6]) + add_constant_[i] + words[i];
uint32_t temp2 = big_sigma0(d[0]) + maj(d[0], d[1], d[2]);
d[7] = d[6];
d[6] = d[5];
d[5] = d[4];
d[4] = d[3] + temp1;
d[3] = d[2];
d[2] = d[1];
d[1] = d[0];
d[0] = temp1 + temp2;
}
for (int i = 0; i < 8; ++i)
{
(*_message_digest)[i] += d[i];
}
return true;
}
else
{
return false;
}
}
bool Sha256::produceFinalHashValue(const std::vector<uint32_t>& input,
std::vector<uint8_t>* _output) const
{
if (_output)
{
_output->clear();
for (auto it = input.begin(); it != input.end(); ++it)
{
for (int i = 0; i < 4; i++)
{
_output->push_back(static_cast<uint8_t>((*it) >> (24 - 8 * i)));
}
}
return true;
}
else
{
return false;
}
}
} // namespace ly

View File

@@ -0,0 +1,144 @@
/*
* Filename: sha256.hpp
* Author: L.Y.
* Brief: SHA256算法实现
* Version: V1.0.0
* Update log:
* 120191108-20191113 V1.0.0
* 1、初次版本。
* TODO:
* Attention:
* 1输入信息中有中文时得到的数字指纹与使用SHA256在线加密工具得到数字指纹可能不相同。
* 原因是中文的编码方式不同。
*/
#ifndef SHA256_HPP
#define SHA256_HPP
#include <stdint.h>
#include <string>
#include <vector>
namespace digest
{
//
// \brief: SHA256算法实现
//
class Sha256
{
public:
//! 默认构造函数
Sha256() {}
//! 析构函数
virtual ~Sha256() {}
/** @brief: 使用SHA256算法获取输入信息的摘要数字指纹
@param[in] message: 输入信息
@param[out] _digest: 摘要(数字指纹)
@return: 是否成功
*/
bool encrypt(const std::vector<uint8_t>& message,
std::vector<uint8_t>* _digest);
/** @brief: 获取十六进制表示的信息摘要(数字指纹)
@param[in] message: 输入信息
@return: 十六进制表示的信息摘要(数字指纹)
*/
std::string getHexMessageDigest(const std::string& message);
protected:
/////// SHA256算法中定义的6种逻辑运算 ///////
inline uint32_t ch(uint32_t x, uint32_t y, uint32_t z) const;
inline uint32_t maj(uint32_t x, uint32_t y, uint32_t z) const;
inline uint32_t big_sigma0(uint32_t x) const;
inline uint32_t big_sigma1(uint32_t x) const;
inline uint32_t small_sigma0(uint32_t x) const;
inline uint32_t small_sigma1(uint32_t x) const;
/** @brief: SHA256算法对输入信息的预处理包括“附加填充比特”和“附加长度值”
附加填充比特: 在报文末尾进行填充先补第一个比特为1然后都补0直到长度满足对512取模后余数是448。需要注意的是信息必须进行填充。
附加长度值: 用一个64位的数据来表示原始消息填充前的消息的长度并将其补到已经进行了填充操作的消息后面。
@param[in][out] _message: 待处理的信息
@return: 是否成功
*/
bool preprocessing(std::vector<uint8_t>* _message) const;
/** @brief: 将信息分解成连续的64Byte大小的数据块
@param[in] message: 输入信息长度为64Byte的倍数
@param[out] _chunks: 输出数据块
@return: 是否成功
*/
bool breakTextInto64ByteChunks(const std::vector<uint8_t>& message,
std::vector<std::vector<uint8_t>>* _chunks) const;
/** @brief: 由64Byte大小的数据块构造出64个4Byte大小的字。
构造算法前16个字直接由数据块分解得到其余的字由如下迭代公式得到
W[t] = small_sigma1(W[t-2]) + W[t-7] + small_sigma0(W[t-15]) + W[t-16]
@param[in] chunk: 输入数据块大小为64Byte
@param[out] _words: 输出字
@return: 是否成功
*/
bool structureWords(const std::vector<uint8_t>& chunk,
std::vector<uint32_t>* _words) const;
/** @breif: 基于64个4Byte大小的字进行64次循环加密
@param[in] words: 64个4Byte大小的字
@param[in][out] _message_digest: 信息摘要
@return: 是否成功
*/
bool transform(const std::vector<uint32_t>& words,
std::vector<uint32_t>* _message_digest) const;
/** @brief: 输出最终的哈希值(数字指纹)
@param[in] input: 步长为32bit的哈希值
@param[out] _output: 步长为8bit的哈希值
@return: 是否成功
*/
bool produceFinalHashValue(const std::vector<uint32_t>& input,
std::vector<uint8_t>* _output) const;
private:
static std::vector<uint32_t> initial_message_digest_; // 在SHA256算法中的初始信息摘要这些常量是对自然数中前8个质数的平方根的小数部分取前32bit而来。
static std::vector<uint32_t> add_constant_; // 在SHA256算法中用到64个常量这些常量是对自然数中前64个质数的立方根的小数部分取前32bit而来。
};
///////////////////////////////// 内联函数&模版函数的定义 /////////////////////////////////////////
inline uint32_t Sha256::ch(uint32_t x, uint32_t y, uint32_t z) const
{
return (x & y) ^ ((~x) & z);
}
inline uint32_t Sha256::maj(uint32_t x, uint32_t y, uint32_t z) const
{
return (x & y) ^ (x & z) ^ (y & z);
}
inline uint32_t Sha256::big_sigma0(uint32_t x) const
{
return (x >> 2 | x << 30) ^ (x >> 13 | x << 19) ^ (x >> 22 | x << 10);
}
inline uint32_t Sha256::big_sigma1(uint32_t x) const
{
return (x >> 6 | x << 26) ^ (x >> 11 | x << 21) ^ (x >> 25 | x << 7);
}
inline uint32_t Sha256::small_sigma0(uint32_t x) const
{
return (x >> 7 | x << 25) ^ (x >> 18 | x << 14) ^ (x >> 3);
}
inline uint32_t Sha256::small_sigma1(uint32_t x) const
{
return (x >> 17 | x << 15) ^ (x >> 19 | x << 13) ^ (x >> 10);
}
} // namespace ly
#endif // SHA256_HPP

View File

@@ -0,0 +1,118 @@
#include <utility>
#include "../thirdparty/base64/base64.h"
#include "sign.h"
#include "RSASign.h"
#include "tool.h"
namespace signutil {
string createSign(map<string, string> params, const string& privateKeyFilepath, const string& signType) {
string content = getSignContent(std::move(params));
return sign(content, privateKeyFilepath, "");
}
string sign(const string& content, const string& privateKeyFilepath, const string& hash) {
BIO *bufio = NULL;
RSA *rsa = NULL;
EVP_PKEY *evpKey = NULL;
bool verify = false;
EVP_MD_CTX ctx;
int result = 0;
unsigned int size = 0;
char *sign = NULL;
std::string signStr = "";
//bufio = BIO_new_mem_buf((void*)private_key, -1);
//if (bufio == NULL) {
// ERR("BIO_new_mem_buf failed");
// goto safe_exit;
//}
bufio = BIO_new(BIO_s_file());
// 读取私钥文件
BIO_read_filename(bufio, privateKeyFilepath.c_str());
// 私钥字符串转换成私钥对象
rsa = PEM_read_bio_RSAPrivateKey(bufio, NULL, NULL, NULL);
if (rsa == NULL) {
ERR("PEM_read_bio_RSAPrivateKey failed");
goto safe_exit;
}
evpKey = EVP_PKEY_new();
if (evpKey == NULL) {
ERR("EVP_PKEY_new failed");
goto safe_exit;
}
if ((result = EVP_PKEY_set1_RSA(evpKey, rsa)) != 1) {
ERR("EVP_PKEY_set1_RSA failed");
goto safe_exit;
}
EVP_MD_CTX_init(&ctx);
// SHA256签名
if (result == 1 && (result = EVP_SignInit_ex(&ctx,
EVP_sha256(), NULL)) != 1) {
ERR("EVP_SignInit_ex failed");
}
if (result == 1 && (result = EVP_SignUpdate(&ctx,
content.c_str(), content.size())) != 1) {
ERR("EVP_SignUpdate failed");
}
size = EVP_PKEY_size(evpKey);
sign = (char*)malloc(size+1);
memset(sign, 0, size+1);
if (result == 1 && (result = EVP_SignFinal(&ctx,
(unsigned char*)sign,
&size, evpKey)) != 1) {
ERR("EVP_SignFinal failed");
}
if (result == 1) {
verify = true;
} else {
ERR("verify failed");
}
signStr = base64_encode((const unsigned char*)sign, size);
EVP_MD_CTX_cleanup(&ctx);
free(sign);
safe_exit:
if (rsa != NULL) {
RSA_free(rsa);
rsa = NULL;
}
if (evpKey != NULL) {
EVP_PKEY_free(evpKey);
evpKey = NULL;
}
if (bufio != NULL) {
BIO_free_all(bufio);
bufio = NULL;
}
return signStr;
}
string getSignContent(map<string, string> params){
map<string, string>::iterator iter;
string content;
for(iter = params.begin(); iter != params.end(); iter++) {
content.append("&").append(iter->first + "=" + iter->second);
}
return content.substr(1);
}
void ERR(const string &msg) {
throw msg;
}
}

View File

@@ -0,0 +1,30 @@
#ifndef SDK_CXX_SIGN_H
#define SDK_CXX_SIGN_H
#include <map>
#include <iostream>
#include <openssl/objects.h>
#include <openssl/rsa.h>
#include <openssl/pem.h>
#include <openssl/bio.h>
#include <openssl/err.h>
#include <string>
using namespace std;
namespace signutil {
string createSign(map<string, string> params, const string& privateKeyFilepath, const string& signType);
string sign(const string& content, const string& privateKeyFilepath, const string& hash);
string getSignContent(map<string, string> params);
void ERR(const string &msg);
}
#endif //SDK_CXX_SIGN_H

View File

@@ -0,0 +1,2 @@
#include "stdafx.h"

View File

@@ -0,0 +1,6 @@
#pragma once
#include "targetver.h"

View File

@@ -0,0 +1 @@

View File

@@ -0,0 +1,174 @@
#include <clocale>
#include "tool.h"
#include <map>
#include <fstream>
#include <sstream>
namespace tool {
bool endWith(const string &str, const string &tail) {
return str.compare(str.size() - tail.size(), tail.size(), tail) == 0;
}
bool startWith(const string &str, const string &head) {
return str.compare(0, head.size(), head) == 0;
}
string getTime() {
time_t timep;
time(&timep);
char tmp[64];
strftime(tmp, sizeof(tmp), "%Y-%m-%d %H:%M:%S", localtime(&timep));
return tmp;
}
int parse_url(char *url, char **serverstrp, int *portp, char **pathstrp) {
char buf[256];
int serverlen, numread = 0;
/* go through the url */
/* reset url to point PAST the http:// */
/* assume it's always 7 chars! */
string _url = url;
bool isHttps = startWith(_url, "https");
int len = 7;
if (isHttps) {
len = 8;
}
url = url + len;
/* no http:// now... server is simply up to the next / or : */
sscanf(url, "%255[^/:]", buf);
serverlen = strlen(buf);
*serverstrp = (char *) malloc(serverlen + 1);
strcpy(*serverstrp, buf);
if (url[serverlen] == ':') {
/* get the port */
sscanf(&url[serverlen + 1], "%d%n", portp, &numread);
/* add one to go PAST it */
numread++;
} else {
if (isHttps) {
*portp = 443;
} else {
*portp = 80;
}
}
/* the path is a pointer into the rest of url */
*pathstrp = &url[serverlen + numread];
return 0;
}
std::string url_encode(const std::string &str) {
std::string strTemp = "";
size_t length = str.length();
for (size_t i = 0; i < length; i++) {
if (isalnum((unsigned char) str[i]) ||
(str[i] == '-') ||
(str[i] == '_') ||
(str[i] == '.') ||
(str[i] == '~'))
strTemp += str[i];
else if (str[i] == ' ')
strTemp += "+";
else {
strTemp += '%';
strTemp += ToHex((unsigned char) str[i] >> 4);
strTemp += ToHex((unsigned char) str[i] % 16);
}
}
return strTemp;
}
std::string url_decode(const std::string &str) {
std::string strTemp = "";
size_t length = str.length();
for (size_t i = 0; i < length; i++) {
if (str[i] == '+') strTemp += ' ';
else if (str[i] == '%') {
assert(i + 2 < length);
unsigned char high = FromHex((unsigned char) str[++i]);
unsigned char low = FromHex((unsigned char) str[++i]);
strTemp += high * 16 + low;
} else strTemp += str[i];
}
return strTemp;
}
unsigned char ToHex(unsigned char x) {
return x > 9 ? x + 55 : x + 48;
}
unsigned char FromHex(unsigned char x) {
unsigned char y;
if (x >= 'A' && x <= 'Z') y = x - 'A' + 10;
else if (x >= 'a' && x <= 'z') y = x - 'a' + 10;
else if (x >= '0' && x <= '9') y = x - '0';
else
assert(0);
return y;
}
string mapToJson(std::map<string, string> map_info) {
// Json::Value jObject;
// for (map<string, string>::const_iterator iter = map_info.begin( ); iter != map_info.end( ); ++iter)
// {
// jObject[iter->first] = iter->second;
// }
// return jObject.toStyledString();
return "{}";
}
string getFilename(string filepath) {
{
if (filepath.empty()) {
return "";
}
std::string::size_type iPos;
#ifdef Q_OS_WIN
iPos = strFullName.find_last_of('\\') + 1;
#else
iPos = filepath.find_last_of('/') + 1;
#endif
return filepath.substr(iPos, filepath.length() - iPos);
}
}
string getFileContent(string filepath) {
ifstream fin(filepath);
stringstream buffer;
buffer << fin.rdbuf();
string fileContent(buffer.str());
fin.close();
return fileContent;
}
std::string replace(const char *pszSrc, const char *pszOld, const char *pszNew)
{
std::string strContent, strTemp;
strContent.assign( pszSrc );
std::string::size_type nPos = 0;
while( true )
{
nPos = strContent.find(pszOld, nPos);
strTemp = strContent.substr(nPos+strlen(pszOld), strContent.length());
if ( nPos == std::string::npos )
{
break;
}
strContent.replace(nPos,strContent.length(), pszNew );
strContent.append(strTemp);
nPos +=strlen(pszNew) - strlen(pszOld)+1; //防止重复替换 避免死循环
}
return strContent;
}
}

View File

@@ -0,0 +1,52 @@
#ifndef SDK_CXX_TOOL_H
#define SDK_CXX_TOOL_H
#include <string>
#include <map>
using namespace std;
namespace tool {
bool endWith(const string &str, const string &tail);
bool startWith(const string &str, const string &head);
string getTime();
int parse_url(char *url, char **serverstrp, int *portp, char **pathstrp);
std::string url_encode(const std::string &szToEncode);
std::string url_decode(const std::string &SRC);
unsigned char ToHex(unsigned char x);
unsigned char FromHex(unsigned char x);
string mapToJson(std::map<string, string> m);
string getFilename(string filepath);
string getFileContent(string filepath);
/**
* 函数:
* replace替换字符串
* 参数:
* pszSrc源字符串
* pszOld需要替换的字符串
* pszNew新字符串
* 返回值:
* 返回替换后的字符串
* 备注:
* 需要添加#include <string>头文件
* ssdwujianhua 2017/08/30
*/
std::string replace(const char *pszSrc, const char *pszOld, const char *pszNew);
}
#endif //SDK_CXX_TOOL_H