/*base64.h*/
#ifndef __BASE64_H__
#define __BASE64_H__
#include
std::string base64_encode(unsigned char const* , unsigned int len);
std::string base64_decode(std::string const& s);
#endif
/**
* \file sm4.h
*/
#ifndef XYSSL_SM4_H
#define XYSSL_SM4_H
#define SM4_ENCRYPT 1
#define SM4_DECRYPT 0
/**
* \brief SM4 context structure
*/
typedef struct
{
int mode; /*!< encrypt/decrypt */
unsigned long sk[32]; /*!< SM4 subkeys */
}
sm4_context;
#ifdef __cplusplus
extern "C" {
#endif
/**
* \brief SM4 key schedule (128-bit, encryption)
*
* \param ctx SM4 context to be initialized
* \param key 16-byte secret key
*/
void sm4_setkey_enc( sm4_context *ctx, unsigned char key[16] );
/**
* \brief SM4 key schedule (128-bit, decryption)
*
* \param ctx SM4 context to be initialized
* \param key 16-byte secret key
*/
void sm4_setkey_dec( sm4_context *ctx, unsigned char key[16] );
/**
* \brief SM4-ECB block encryption/decryption
* \param ctx SM4 context
* \param mode SM4_ENCRYPT or SM4_DECRYPT
* \param length length of the input data
* \param input input block
* \param output output block
*/
void sm4_crypt_ecb( sm4_context *ctx,
int mode,
int length,
unsigned char *input,
unsigned char *output);
/**
* \brief SM4-CBC buffer encryption/decryption
* \param ctx SM4 context
* \param mode SM4_ENCRYPT or SM4_DECRYPT
* \param length length of the input data
* \param iv initialization vector (updated after use)
* \param input buffer holding the input data
* \param output buffer holding the output data
*/
void sm4_crypt_cbc( sm4_context *ctx,
int mode,
int length,
unsigned char iv[16],
unsigned char *input,
unsigned char *output );
#ifdef __cplusplus
}
#endif
#endif /* sm4.h */
#include
#include
#include
#include "sm4.h"
#include "base64.h"
#define SIZE 10250
int main()
{
char data[] = {"{\"identifierType\":\"1\",\"identifier\":\"66666666666\",\"pushId\":\"66666666666\",\"appType\":\"1\",\"order\":[{\"orderId\":\"0\",\"orderType\":\"1\",\"serviceId\":\"8201\",\"marketId\":\"2\",\"productType\":\"1\",\"stockCode\":\"600000\",\"stockName\":\"浦发银行\",\"price\":\"14\",\"up\":\"1\"},{\"orderId\":\"0\",\"orderType\":\"1\",\"serviceId\":\"8201\",\"marketId\":\"2\",\"productType\":\"1\",\"stockCode\":\"600000\",\"stockName\":\"浦发银行\",\"price\":\"12\",\"up\":\"2\"},{\"orderId\":\"0\",\"orderType\":\"1\",\"serviceId\":\"8202\",\"marketId\":\"2\",\"productType\":\"1\",\"stockCode\":\"600000\",\"stockName\":\"浦发银行\",\"price\":\"0.02\",\"up\":\"1\"},{\"orderId\":\"0\",\"orderType\":\"1\",\"se viceId\":\"8202\",\"marketId\":\"2\",\"productType\":\"1\",\"stockCode\":\"600000\",\"stockNa me\":\"浦发银行\",\"price\":\"0.02\",\"up\":\"2\"}]}"}; unsigned char key[16] = {1,255,38,94,66,165,29,37,98,192,231,186,13,2,169,201};
unsigned char *src = (unsigned char *)data;
size_t srclen = strlen(data);
unsigned char sm4Src[SIZE * 10];
std::string base64Src;
std::string base64Dst;
std::string sm4StrDst;
unsigned char sm4Dst[SIZE];
unsigned char dst[10240];
char buff[10240] = {0};
/
sm4_context ctx;
sm4_setkey_enc(&ctx,key);
sm4_crypt_ecb(&ctx,SM4_ENCRYPT,srclen,src,sm4Src);
size_t sm4SrcLen = 16 - srclen % 16 + srclen;
base64Src = base64_encode(sm4Src,sm4SrcLen);
/
base64Dst = base64Src;
sm4StrDst = base64_decode(base64Dst);
memcpy(sm4Dst,sm4StrDst.c_str(),sm4StrDst.size());
sm4_setkey_dec(&ctx,key);
sm4_crypt_ecb(&ctx,SM4_DECRYPT,sm4StrDst.size(),sm4Dst,dst);
memcpy(buff,dst,sm4StrDst.size());
buff[sm4StrDst.size()] = 0;
std::cout << buff << std::endl;
return 0;
}
#include "base64.h"
#include
static const std::string base64_chars =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789+/";
static inline bool is_base64(unsigned char c) {
return (isalnum(c) || (c == '+') || (c == '/'));
}
std::string base64_encode(unsigned char const* bytes_to_encode, unsigned int in_len) {
std::string ret;
int i = 0;
int j = 0;
unsigned char char_array_3[3];
unsigned char char_array_4[4];
while (in_len--) {
char_array_3[i++] = *(bytes_to_encode++);
if (i == 3) { //每获取三个字节,就进行编码.
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
char_array_4[3] = char_array_3[2] & 0x3f;
for(i = 0; (i <4) ; i++)
ret += base64_chars[char_array_4[i]]; //查字典
i = 0;
}
}
if (i)
{
for(j = i; j < 3; j++)
char_array_3[j] = '\0';
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
char_array_4[3] = char_array_3[2] & 0x3f;
for (j = 0; (j < i + 1); j++) //i=1/2:至少编码8/16bit,实际编码12/18bit,产生2/3bytes.
ret += base64_chars[char_array_4[j]];
while((i++ < 3))
ret += '=';
}
return ret;
}
std::string base64_decode(std::string const& encoded_string) {
int in_len = encoded_string.size();
int i = 0;
int j = 0;
int in_ = 0;
unsigned char char_array_4[4], char_array_3[3];
std::string ret;
while (in_len-- && ( encoded_string[in_] != '=') && is_base64(encoded_string[in_])) {
char_array_4[i++] = encoded_string[in_]; in_++;
if (i ==4) {
for (i = 0; i <4; i++)
char_array_4[i] = base64_chars.find(char_array_4[i]);
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
for (i = 0; (i < 3); i++)
ret += char_array_3[i];
i = 0;
}
}
if (i) {
for (j = i; j <4; j++)
char_array_4[j] = 0;
for (j = 0; j <4; j++)
char_array_4[j] = base64_chars.find(char_array_4[j]);
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
for (j = 0; (j < i - 1); j++) ret += char_array_3[j];
}
return ret;
}
base64_chars有64位可显示符号,即占6bit,作为字典.
每三个字节为一组(24bit),进行编码:
1,取出第一个6bit,查字典,字典结果为编码.
0xfc:1111 1100 >> 2 == 11 1111
2,取出第二个6bit,查字典,字典结果为编码.
0x03:0000 0011 << 4 == 11 0000
0xf0:1111 0000 >> 4 == 00 1111
3,取出第三个6bit,查字典,字典结果为编码.
0x0f:0000 1111 << 2 == 11 1100
0xc0:1100 0000 >> 6 == 00 0011
4,取出第四个6bit,查字典,字典结果为编码.
0x3f:0011 1111 == 11 1111
如果最后一组只有i=1/2个字节:
补0填充.
i=1 ---8bit需编码
char_arr_3[0]=原值.
char_arr_3[1]=0.
char_arr_3[2]=0.
编码后:
char_arr_4[0]//编码正常
char_arr_4[1]//编码正常
char_arr_4[2]//编码不应有 赋值'='
char_arr_4[3]//编码不应有 赋值'='
i=2 ---16bit需编码
char_arr_3[0]=原值.
char_arr_3[1]=原值.
char_arr_3[2]=0.
编码后:
char_arr_4[0]//编码正常
char_arr_4[1]//编码正常
char_arr_4[2]//编码正常
char_arr_4[3]//编码不应有 赋值'='