C#与C程序通讯时,为了数据安全,要对数据进行DES_cbc_pkcs7加密,这是C的实现

/**//*
功能:用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;
}

QQ:273352165
evlon#126.com
转载请注明出处。
标签:
POS
,
DES
,
PKCS7
,
C++
,
C#
,
加密
,
解密
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· Qt个人项目总结 —— MySQL数据库查询与断言