C与C#通讯加密之C语言DES的cbc pkcs7的实现
/*
功能:用mode = cbc , padding = pkcs7 来加密
如果to == NULL, 则返回加密后数据的长度
书写:evlon ,QQ:273352165
*/
int des_ecb_pkcs7_encrypt(uchar* from, int nLength, uchar * to, uchar key[])
{
int nSize = nLength % 8 ?(nLength + 7) / 8 * 8 : nLength + 8;
if(to == NULL)
{
//计算长度
return nSize;
}
else
{
deskey(key,EN0);
uchar endBuf[8];
int i=0;
for(; i < nSize; i+=8)
{
uchar* ps = NULL,* pd = NULL;
if(nLength - i >= 8)
{
ps = from + i;
pd = to + i;
}
else
{
memset(&endBuf, i + 8 - nLength, sizeof(endBuf));
memcpy(&endBuf,from + i,nLength - i);
ps = endBuf;
pd = to + i;
}
des(ps,pd);
}
return i;
}
}
int des_ecb_pkcs7_decrypt(uchar* from, int nLength, uchar * to, uchar key[])
{
if(nLength % 8)
return 0; //数据不正确
deskey(key,DE1);
int i = 0;
for(; i < nLength; i+=8)
{
if(nLength - i > 8)
{
des(from + i,to + i);
}
else
{
uchar endBuf[8];
des(from + i,endBuf);
//去除数据尾
uchar chEnd = endBuf[7];
if(chEnd > 0 && chEnd < 9)
{
//有可能是填充字符,去除掉
for(int j = 7; j >= 8 - chEnd; --j)
{
if(endBuf[j] != chEnd)
return 0;
}
memcpy(to + i, endBuf, 8 - chEnd);
return i + 8 - chEnd;
}
else
{
return 0;
}
}
}
return 0;
}
/*
功能:用mode = cbc , padding = pkcs7 来加密
如果to == NULL, 则返回加密后数据的长度
书写:evlon ,QQ:273352165
*/
int des_cbc_pkcs7_encrypt(uchar* from, int nLength, uchar * to, uchar key[],uchar iv[])
{
int nSize = nLength % 8 ?(nLength + 7) / 8 * 8 : nLength + 8;
if(to == NULL)
{
//计算长度
return nSize;
}
else
{
deskey(key,EN0);
uchar* fromBackup = from;
from = (uchar*)malloc(nSize); //申请内存
memcpy(from,fromBackup,nLength);
memset(from + nLength, nSize - nLength,nSize - nLength);
uchar preEnc[8];
memcpy(preEnc,iv,8);
//加密块
int i=0;
for(; i < nSize; i+=8)
{
uchar* ps = from + i;
uchar* pd = to + i;
//XOR
for(int j = 0; j < 8; ++j)
{
ps[j] ^= preEnc[j];
}
des(ps,pd);
//保存前一个输出
memcpy(preEnc, pd,8);
}
free(from);
//memcpy(to + i,preEnc,8);
return i;
}
}
int des_cbc_pkcs7_decrypt(uchar* from, int nLength, uchar * to, uchar key[], uchar iv[])
{
if(nLength % 8)
return 0; //数据不正确
uchar* toBackup = to;
to = (uchar*)malloc(nLength); //申请内存
//XOR
uchar preEnc[8];
memcpy(preEnc,iv,8);
deskey(key,DE1);
int i = 0;
for(; i < nLength; i+=8)
{
uchar* ps = from + i;
uchar* pd = to + i;
des(ps,pd);
//XOR
for(int j = 0; j < 8; ++j)
{
pd[j] ^= preEnc[j];
}
//保存前一个输出
memcpy(preEnc, ps,8);
}
//去除数据尾
uchar chEnd = to[nLength - 1];
if(chEnd > 0 && chEnd < 9)
{
//有可能是填充字符,去除掉
for(int j = nLength - 1; j >= nLength - chEnd; --j)
{
if(to[j] != chEnd)
return 0;
}
int nSize =nLength - chEnd;
memcpy(toBackup, to, nSize);
free(to);
return nSize;
}
else
{
//数据格式不正确
free(to);return 0;
}
return 0;
}
功能:用mode = cbc , padding = pkcs7 来加密
如果to == NULL, 则返回加密后数据的长度
书写:evlon ,QQ:273352165
*/
int des_ecb_pkcs7_encrypt(uchar* from, int nLength, uchar * to, uchar key[])
{
int nSize = nLength % 8 ?(nLength + 7) / 8 * 8 : nLength + 8;
if(to == NULL)
{
//计算长度
return nSize;
}
else
{
deskey(key,EN0);
uchar endBuf[8];
int i=0;
for(; i < nSize; i+=8)
{
uchar* ps = NULL,* pd = NULL;
if(nLength - i >= 8)
{
ps = from + i;
pd = to + i;
}
else
{
memset(&endBuf, i + 8 - nLength, sizeof(endBuf));
memcpy(&endBuf,from + i,nLength - i);
ps = endBuf;
pd = to + i;
}
des(ps,pd);
}
return i;
}
}
int des_ecb_pkcs7_decrypt(uchar* from, int nLength, uchar * to, uchar key[])
{
if(nLength % 8)
return 0; //数据不正确
deskey(key,DE1);
int i = 0;
for(; i < nLength; i+=8)
{
if(nLength - i > 8)
{
des(from + i,to + i);
}
else
{
uchar endBuf[8];
des(from + i,endBuf);
//去除数据尾
uchar chEnd = endBuf[7];
if(chEnd > 0 && chEnd < 9)
{
//有可能是填充字符,去除掉
for(int j = 7; j >= 8 - chEnd; --j)
{
if(endBuf[j] != chEnd)
return 0;
}
memcpy(to + i, endBuf, 8 - chEnd);
return i + 8 - chEnd;
}
else
{
return 0;
}
}
}
return 0;
}
/*
功能:用mode = cbc , padding = pkcs7 来加密
如果to == NULL, 则返回加密后数据的长度
书写:evlon ,QQ:273352165
*/
int des_cbc_pkcs7_encrypt(uchar* from, int nLength, uchar * to, uchar key[],uchar iv[])
{
int nSize = nLength % 8 ?(nLength + 7) / 8 * 8 : nLength + 8;
if(to == NULL)
{
//计算长度
return nSize;
}
else
{
deskey(key,EN0);
uchar* fromBackup = from;
from = (uchar*)malloc(nSize); //申请内存
memcpy(from,fromBackup,nLength);
memset(from + nLength, nSize - nLength,nSize - nLength);
uchar preEnc[8];
memcpy(preEnc,iv,8);
//加密块
int i=0;
for(; i < nSize; i+=8)
{
uchar* ps = from + i;
uchar* pd = to + i;
//XOR
for(int j = 0; j < 8; ++j)
{
ps[j] ^= preEnc[j];
}
des(ps,pd);
//保存前一个输出
memcpy(preEnc, pd,8);
}
free(from);
//memcpy(to + i,preEnc,8);
return i;
}
}
int des_cbc_pkcs7_decrypt(uchar* from, int nLength, uchar * to, uchar key[], uchar iv[])
{
if(nLength % 8)
return 0; //数据不正确
uchar* toBackup = to;
to = (uchar*)malloc(nLength); //申请内存
//XOR
uchar preEnc[8];
memcpy(preEnc,iv,8);
deskey(key,DE1);
int i = 0;
for(; i < nLength; i+=8)
{
uchar* ps = from + i;
uchar* pd = to + i;
des(ps,pd);
//XOR
for(int j = 0; j < 8; ++j)
{
pd[j] ^= preEnc[j];
}
//保存前一个输出
memcpy(preEnc, ps,8);
}
//去除数据尾
uchar chEnd = to[nLength - 1];
if(chEnd > 0 && chEnd < 9)
{
//有可能是填充字符,去除掉
for(int j = nLength - 1; j >= nLength - chEnd; --j)
{
if(to[j] != chEnd)
return 0;
}
int nSize =nLength - chEnd;
memcpy(toBackup, to, nSize);
free(to);
return nSize;
}
else
{
//数据格式不正确
free(to);return 0;
}
return 0;
}
测试代码如下:
//把字节数组转换成字串
int Byte2String(uchar* bytes, int nLength, char* pszout)
{
if(!pszout)
{
return nLength * 3;
}
else
{
for (int i = 0; i < nLength; ++i)
{
//sb.AppendFormat("{0} ", b.ToString("X2"));
sprintf(pszout + i * 3,"%2X ",bytes[i]);
}
*(pszout + nLength * 3 -1) = '\0';
return nLength * 3;
}
}
/////////////////////////////////////////////////
///////// 测试代码 ///////////
/////////////////////////////////////////////////
void cbcDesTest1()
{
uchar key[8] = {1,2,3,4,5,6,7,8};
uchar iv[8] = {1,2,3,4,5,6,7,8};
uchar text[25] = "123456789abcdef中国人ok";
uchar *output = NULL;
uchar text2[sizeof(text)];
memset(&text2,0,sizeof(text2));
int nLength = des_cbc_pkcs7_encrypt(text,24,NULL,key,iv);
output = new uchar[nLength];
memset(output,0,nLength);
des_cbc_pkcs7_encrypt(text,24,output,key,iv);
des_cbc_pkcs7_decrypt(output,24,text2,key,iv);
delete[] output;
output = NULL;
}
void cbcDesTest2()
{
char szPrint[1024];
uchar key[8] = {1,2,3,4,5,6,7,8};
uchar iv[8] = {1,2,3,4,5,6,7,8};
StringPack pack;
pack.OpCode = 2;
pack.CharEnd = '8';
strcpy(pack.Name, "123456789abcdef中国人ok");
uchar* pPack = (uchar*)&pack;
//计算数据长度
int nLength = des_cbc_pkcs7_encrypt(pPack,sizeof(StringPack),NULL,key,iv);
uchar* output = new uchar[nLength];
memset(output,0,nLength);
//打印出来
Byte2String(pPack,sizeof(StringPack),szPrint);
printf("%s\n",szPrint);
//加密
des_cbc_pkcs7_encrypt(pPack,sizeof(StringPack),output,key,iv);
//打印出来
Byte2String(output,nLength,szPrint);
printf("%s\n",szPrint);
//检验一下加密结果,现在解密
uchar *packData = new uchar[nLength];
memset(packData,0,nLength);
des_cbc_pkcs7_decrypt(output,nLength,packData,key,iv);
//好了,我们看一下结果吧
StringPack* pack2 = (StringPack*)packData;
//清理内存
delete[] packData;
output = NULL;
delete[] output;
output = NULL;
}
void cbcDesTest3()
{
uchar key[8] = {1,2,3,4,5,6,7,8};
uchar iv[8] = {1,2,3,4,5,6,7,8};
// 7 位长
{
uchar text[] = {0xF0, 0xA5, 0xED, 0x9F, 0x83, 0x8A, 0xE0};
uchar output[1024] = {0};
uchar text2[1024] = {0};
int nRet = des_cbc_pkcs7_encrypt(text,sizeof(text),output,key,iv);
char szPrint[1024];
//打印出来
Byte2String(output,nRet,szPrint);
printf("(%d)\n%s\n",nRet,szPrint);
nRet = des_cbc_pkcs7_decrypt(output,nRet,text2,key,iv);
//打印出来
Byte2String(text2,nRet,szPrint);
printf("(%d)\n%s\n",nRet,szPrint);
}
// 8 位长
{
uchar text[] = {0xF0, 0xA5, 0xED, 0x9F, 0x83, 0x8A, 0xE0, 0xE2};
uchar output[1024] = {0};
uchar text2[1024] = {0};
int nRet = des_cbc_pkcs7_encrypt(text,sizeof(text),output,key,iv);
char szPrint[1024];
//打印出来
Byte2String(output,nRet,szPrint);
printf("(%d)\n%s\n",nRet,szPrint);
nRet = des_cbc_pkcs7_decrypt(output,nRet,text2,key,iv);
//打印出来
Byte2String(text2,nRet,szPrint);
printf("(%d)\n%s\n",nRet,szPrint);
}
// 9 位长
{
uchar text[] = {0xF0, 0xA5, 0xED, 0x9F, 0x83, 0x8A, 0xE0, 0xE2,0xF0};
uchar output[1024] = {0};
uchar text2[1024] = {0};
int nRet = des_cbc_pkcs7_encrypt(text,sizeof(text),output,key,iv);
char szPrint[1024];
//打印出来
Byte2String(output,nRet,szPrint);
printf("(%d)\n%s\n",nRet,szPrint);
nRet = des_cbc_pkcs7_decrypt(output,nRet,text2,key,iv);
//打印出来
Byte2String(text2,nRet,szPrint);
printf("(%d)\n%s\n",nRet,szPrint);
}
// N 位长
{
uchar text[] = {0xF0, 0xA5, 0xED, 0x9F, 0x83, 0x8A, 0xE0, 0xE2,0xF0, 0xA5, 0xED, 0x9F, 0xA5, 0xED, 0x9F, 0xA5, 0xED, 0x9F};
uchar output[1024] = {0};
uchar text2[1024] = {0};
int nRet = des_cbc_pkcs7_encrypt(text,sizeof(text),output,key,iv);
char szPrint[1024];
//打印出来
Byte2String(output,nRet,szPrint);
printf("(%d)\n%s\n",nRet,szPrint);
nRet = des_cbc_pkcs7_decrypt(output,nRet,text2,key,iv);
//打印出来
Byte2String(text2,nRet,szPrint);
printf("(%d)\n%s\n",nRet,szPrint);
}
}
void ecbDesTest1()
{
uchar key[8] = {1,2,3,4,5,6,7,8};
// 7 位长
{
uchar text[] = {0xF0, 0xA5, 0xED, 0x9F, 0x83, 0x8A, 0xE0};
uchar output[1024] = {0};
uchar text2[1024] = {0};
int nRet = des_ecb_pkcs7_encrypt(text,sizeof(text),output,key);
char szPrint[1024];
//打印出来
Byte2String(output,nRet,szPrint);
printf("(%d)\n%s\n",nRet,szPrint);
nRet = des_ecb_pkcs7_decrypt(output,nRet,text2,key);
//打印出来
Byte2String(text2,nRet,szPrint);
printf("(%d)\n%s\n",nRet,szPrint);
}
// 8 位长
{
uchar text[] = {0xF0, 0xA5, 0xED, 0x9F, 0x83, 0x8A, 0xE0, 0xE2};
uchar output[1024] = {0};
uchar text2[1024] = {0};
int nRet = des_ecb_pkcs7_encrypt(text,sizeof(text),output,key);
char szPrint[1024];
//打印出来
Byte2String(output,nRet,szPrint);
printf("(%d)\n%s\n",nRet,szPrint);
nRet = des_ecb_pkcs7_decrypt(output,nRet,text2,key);
//打印出来
Byte2String(text2,nRet,szPrint);
printf("(%d)\n%s\n",nRet,szPrint);
}
// 9 位长
{
uchar text[] = {0xF0, 0xA5, 0xED, 0x9F, 0x83, 0x8A, 0xE0, 0xE2,0xF0};
uchar output[1024] = {0};
uchar text2[1024] = {0};
int nRet = des_ecb_pkcs7_encrypt(text,sizeof(text),output,key);
char szPrint[1024];
//打印出来
Byte2String(output,nRet,szPrint);
printf("(%d)\n%s\n",nRet,szPrint);
nRet = des_ecb_pkcs7_decrypt(output,nRet,text2,key);
//打印出来
Byte2String(text2,nRet,szPrint);
printf("(%d)\n%s\n",nRet,szPrint);
}
// N 位长
{
uchar text[] = {0xF0, 0xA5, 0xED, 0x9F, 0x83, 0x8A, 0xE0, 0xE2,0xF0, 0xA5, 0xED, 0x9F, 0xA5, 0xED, 0x9F, 0xA5, 0xED, 0x9F};
uchar output[1024] = {0};
uchar text2[1024] = {0};
int nRet = des_ecb_pkcs7_encrypt(text,sizeof(text),output,key);
char szPrint[1024];
//打印出来
Byte2String(output,nRet,szPrint);
printf("(%d)\n%s\n",nRet,szPrint);
nRet = des_ecb_pkcs7_decrypt(output,nRet,text2,key);
//打印出来
Byte2String(text2,nRet,szPrint);
printf("(%d)\n%s\n",nRet,szPrint);
}
}
int _tmain(int argc, _TCHAR* argv[])
{
ecbDesTest1();
cbcDesTest1();
cbcDesTest2();
cbcDesTest3();
getchar();
return 0;
}
int Byte2String(uchar* bytes, int nLength, char* pszout)
{
if(!pszout)
{
return nLength * 3;
}
else
{
for (int i = 0; i < nLength; ++i)
{
//sb.AppendFormat("{0} ", b.ToString("X2"));
sprintf(pszout + i * 3,"%2X ",bytes[i]);
}
*(pszout + nLength * 3 -1) = '\0';
return nLength * 3;
}
}
/////////////////////////////////////////////////
///////// 测试代码 ///////////
/////////////////////////////////////////////////
void cbcDesTest1()
{
uchar key[8] = {1,2,3,4,5,6,7,8};
uchar iv[8] = {1,2,3,4,5,6,7,8};
uchar text[25] = "123456789abcdef中国人ok";
uchar *output = NULL;
uchar text2[sizeof(text)];
memset(&text2,0,sizeof(text2));
int nLength = des_cbc_pkcs7_encrypt(text,24,NULL,key,iv);
output = new uchar[nLength];
memset(output,0,nLength);
des_cbc_pkcs7_encrypt(text,24,output,key,iv);
des_cbc_pkcs7_decrypt(output,24,text2,key,iv);
delete[] output;
output = NULL;
}
void cbcDesTest2()
{
char szPrint[1024];
uchar key[8] = {1,2,3,4,5,6,7,8};
uchar iv[8] = {1,2,3,4,5,6,7,8};
StringPack pack;
pack.OpCode = 2;
pack.CharEnd = '8';
strcpy(pack.Name, "123456789abcdef中国人ok");
uchar* pPack = (uchar*)&pack;
//计算数据长度
int nLength = des_cbc_pkcs7_encrypt(pPack,sizeof(StringPack),NULL,key,iv);
uchar* output = new uchar[nLength];
memset(output,0,nLength);
//打印出来
Byte2String(pPack,sizeof(StringPack),szPrint);
printf("%s\n",szPrint);
//加密
des_cbc_pkcs7_encrypt(pPack,sizeof(StringPack),output,key,iv);
//打印出来
Byte2String(output,nLength,szPrint);
printf("%s\n",szPrint);
//检验一下加密结果,现在解密
uchar *packData = new uchar[nLength];
memset(packData,0,nLength);
des_cbc_pkcs7_decrypt(output,nLength,packData,key,iv);
//好了,我们看一下结果吧
StringPack* pack2 = (StringPack*)packData;
//清理内存
delete[] packData;
output = NULL;
delete[] output;
output = NULL;
}
void cbcDesTest3()
{
uchar key[8] = {1,2,3,4,5,6,7,8};
uchar iv[8] = {1,2,3,4,5,6,7,8};
// 7 位长
{
uchar text[] = {0xF0, 0xA5, 0xED, 0x9F, 0x83, 0x8A, 0xE0};
uchar output[1024] = {0};
uchar text2[1024] = {0};
int nRet = des_cbc_pkcs7_encrypt(text,sizeof(text),output,key,iv);
char szPrint[1024];
//打印出来
Byte2String(output,nRet,szPrint);
printf("(%d)\n%s\n",nRet,szPrint);
nRet = des_cbc_pkcs7_decrypt(output,nRet,text2,key,iv);
//打印出来
Byte2String(text2,nRet,szPrint);
printf("(%d)\n%s\n",nRet,szPrint);
}
// 8 位长
{
uchar text[] = {0xF0, 0xA5, 0xED, 0x9F, 0x83, 0x8A, 0xE0, 0xE2};
uchar output[1024] = {0};
uchar text2[1024] = {0};
int nRet = des_cbc_pkcs7_encrypt(text,sizeof(text),output,key,iv);
char szPrint[1024];
//打印出来
Byte2String(output,nRet,szPrint);
printf("(%d)\n%s\n",nRet,szPrint);
nRet = des_cbc_pkcs7_decrypt(output,nRet,text2,key,iv);
//打印出来
Byte2String(text2,nRet,szPrint);
printf("(%d)\n%s\n",nRet,szPrint);
}
// 9 位长
{
uchar text[] = {0xF0, 0xA5, 0xED, 0x9F, 0x83, 0x8A, 0xE0, 0xE2,0xF0};
uchar output[1024] = {0};
uchar text2[1024] = {0};
int nRet = des_cbc_pkcs7_encrypt(text,sizeof(text),output,key,iv);
char szPrint[1024];
//打印出来
Byte2String(output,nRet,szPrint);
printf("(%d)\n%s\n",nRet,szPrint);
nRet = des_cbc_pkcs7_decrypt(output,nRet,text2,key,iv);
//打印出来
Byte2String(text2,nRet,szPrint);
printf("(%d)\n%s\n",nRet,szPrint);
}
// N 位长
{
uchar text[] = {0xF0, 0xA5, 0xED, 0x9F, 0x83, 0x8A, 0xE0, 0xE2,0xF0, 0xA5, 0xED, 0x9F, 0xA5, 0xED, 0x9F, 0xA5, 0xED, 0x9F};
uchar output[1024] = {0};
uchar text2[1024] = {0};
int nRet = des_cbc_pkcs7_encrypt(text,sizeof(text),output,key,iv);
char szPrint[1024];
//打印出来
Byte2String(output,nRet,szPrint);
printf("(%d)\n%s\n",nRet,szPrint);
nRet = des_cbc_pkcs7_decrypt(output,nRet,text2,key,iv);
//打印出来
Byte2String(text2,nRet,szPrint);
printf("(%d)\n%s\n",nRet,szPrint);
}
}
void ecbDesTest1()
{
uchar key[8] = {1,2,3,4,5,6,7,8};
// 7 位长
{
uchar text[] = {0xF0, 0xA5, 0xED, 0x9F, 0x83, 0x8A, 0xE0};
uchar output[1024] = {0};
uchar text2[1024] = {0};
int nRet = des_ecb_pkcs7_encrypt(text,sizeof(text),output,key);
char szPrint[1024];
//打印出来
Byte2String(output,nRet,szPrint);
printf("(%d)\n%s\n",nRet,szPrint);
nRet = des_ecb_pkcs7_decrypt(output,nRet,text2,key);
//打印出来
Byte2String(text2,nRet,szPrint);
printf("(%d)\n%s\n",nRet,szPrint);
}
// 8 位长
{
uchar text[] = {0xF0, 0xA5, 0xED, 0x9F, 0x83, 0x8A, 0xE0, 0xE2};
uchar output[1024] = {0};
uchar text2[1024] = {0};
int nRet = des_ecb_pkcs7_encrypt(text,sizeof(text),output,key);
char szPrint[1024];
//打印出来
Byte2String(output,nRet,szPrint);
printf("(%d)\n%s\n",nRet,szPrint);
nRet = des_ecb_pkcs7_decrypt(output,nRet,text2,key);
//打印出来
Byte2String(text2,nRet,szPrint);
printf("(%d)\n%s\n",nRet,szPrint);
}
// 9 位长
{
uchar text[] = {0xF0, 0xA5, 0xED, 0x9F, 0x83, 0x8A, 0xE0, 0xE2,0xF0};
uchar output[1024] = {0};
uchar text2[1024] = {0};
int nRet = des_ecb_pkcs7_encrypt(text,sizeof(text),output,key);
char szPrint[1024];
//打印出来
Byte2String(output,nRet,szPrint);
printf("(%d)\n%s\n",nRet,szPrint);
nRet = des_ecb_pkcs7_decrypt(output,nRet,text2,key);
//打印出来
Byte2String(text2,nRet,szPrint);
printf("(%d)\n%s\n",nRet,szPrint);
}
// N 位长
{
uchar text[] = {0xF0, 0xA5, 0xED, 0x9F, 0x83, 0x8A, 0xE0, 0xE2,0xF0, 0xA5, 0xED, 0x9F, 0xA5, 0xED, 0x9F, 0xA5, 0xED, 0x9F};
uchar output[1024] = {0};
uchar text2[1024] = {0};
int nRet = des_ecb_pkcs7_encrypt(text,sizeof(text),output,key);
char szPrint[1024];
//打印出来
Byte2String(output,nRet,szPrint);
printf("(%d)\n%s\n",nRet,szPrint);
nRet = des_ecb_pkcs7_decrypt(output,nRet,text2,key);
//打印出来
Byte2String(text2,nRet,szPrint);
printf("(%d)\n%s\n",nRet,szPrint);
}
}
int _tmain(int argc, _TCHAR* argv[])
{
ecbDesTest1();
cbcDesTest1();
cbcDesTest2();
cbcDesTest3();
getchar();
return 0;
}
QQ:273352165
evlon#126.com
转载请注明出处。