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;
}









测试代码如下:

// 把字节数组转换成字串
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[] 
= {0xF00xA50xED0x9F0x830x8A0xE0};
        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[] 
= {0xF00xA50xED0x9F0x830x8A0xE00xE2};
        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[] 
= {0xF00xA50xED0x9F0x830x8A0xE00xE2,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[] 
= {0xF00xA50xED0x9F0x830x8A0xE00xE2,0xF00xA50xED0x9F0xA50xED0x9F0xA50xED0x9F};
        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[] 
= {0xF00xA50xED0x9F0x830x8A0xE0};
        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[] 
= {0xF00xA50xED0x9F0x830x8A0xE00xE2};
        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[] 
= {0xF00xA50xED0x9F0x830x8A0xE00xE2,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[] 
= {0xF00xA50xED0x9F0x830x8A0xE00xE2,0xF00xA50xED0x9F0xA50xED0x9F0xA50xED0x9F};
        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;
}

你可能感兴趣的:(C语言)