四、对解压结果进行Base64解码
解码函数:[ref]
// Base64解码
std::string Base64decode(const char* Data, int DataByte, int& OutByte)
{
//解码表
const char DecodeTable[] =
{
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
62, // '+'
0, 0, 0,
63, // '/'
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, // '0'-'9'
0, 0, 0, 0, 0, 0, 0,
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, // 'A'-'Z'
0, 0, 0, 0, 0, 0,
26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, // 'a'-'z'
};
std::string strDecode;
int nValue;
int i = 0;
while (i < DataByte)
{
if (*Data != '\r' && *Data != '\n')
{
nValue = DecodeTable[*Data++] << 18;
nValue += DecodeTable[*Data++] << 12;
strDecode += (nValue & 0x00FF0000) >> 16;
OutByte++;
if (*Data != '=')
{
nValue += DecodeTable[*Data++] << 6;
strDecode += (nValue & 0x0000FF00) >> 8;
OutByte++;
if (*Data != '=')
{
nValue += DecodeTable[*Data++];
strDecode += nValue & 0x000000FF;
OutByte++;
}
}
i += 4;
}
else
{
Data++;
i++;
}
}
return strDecode;
}
Base64原理:简单来说就是把原本的数据每三个字符(3*8bit)按6bit一组拆分为4组(4*6bit),拆分后每组高位补两个零(4*8)对应64个字符,这64个字符就是"a-z""A-Z""0-9"以及"+""/"和结尾用于补位的"="。
五、使用OpenSSL库进行RSA解密
解密函数:
// RSA解密
bool RSA_decrypt(const std::string &in, std::string &out, const std::string &privatekey, int padding)
{
int lenRSA = 0, lenOut = 0;
std::string tmpfrom;
char tmpto[100];
RSA *rsa = RSA_new();
BIO *keyBIO = NULL;
// 从内存读取私钥
char *chPKey = const_cast<char *>(privatekey.c_str());
if ((keyBIO = BIO_new_mem_buf(chPKey, -1)) == NULL)
{
BIO_free(keyBIO);
return false;
}
if ((rsa = PEM_read_bio_RSAPrivateKey(keyBIO, &rsa, NULL, NULL)) == NULL)
{
BIO_free(keyBIO);
return false;
}
BIO_free(keyBIO);
// 按私钥长度分组解密
lenRSA = RSA_size(rsa);
for (int index = 0; index < in.length(); index += (lenRSA))
{
tmpfrom = in.substr(index, lenRSA);
if ((lenOut = RSA_private_decrypt((lenRSA), (const unsigned char*)tmpfrom.c_str(), (unsigned char*)tmpto, rsa, padding)) < 0)
{
return false;
}
out.append(tmpto, 100);
memset(tmpto, 0, sizeof(tmpto));
}
RSA_free(rsa);
return true;
}
padding使用PKCS#1,对密码学没有了解,一开始不知道分组解密,查阅了PKCS#1的规范意识到密文长度远远超过了私钥长度怪不得无法解密,后来又不晓得分组长度是怎么定的,浪费了不少时间,实际情况是需要对密文按照私钥长度进行分组,然后才能分别对每组密文正确解密,最后拼接成完整的明文数据。
需要提高的地方:
0.内存管理要慎之又慎;
1.注意sizeof的参数是指针时返回的是指针类型所占空间,数组和指针还是有所不同的!——sizeof是运算符,其值在编译时即计算好了,参数可以是数组、指针、类型、对象、函数等。它的功能是:获得保证能容纳实现所建立的最大对象的字节大小。由于在编译时计算,因此sizeof不能用来返回动态分配的内存空间的大小;[sizeof()、strlen()、string中length()和size()]
2.还有就是在使用指针作为参数传递时,尽量加上长度参数限制以防内存越界;
3.对于复杂类型需要慎用memset;[老生常谈,正确使用memset]