zoukankan      html  css  js  c++  java
  • 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;
    }

  • 相关阅读:
    高斯消元
    Luogu P2068 统计和
    Luogu P1892 [BOI2003]团伙
    Luogu P2866 [USACO06NOV]糟糕的一天Bad Hair Day
    Luogu P3916 图的遍历
    Luogu P1041 [2003NOIP提高组]传染病控制
    Luogu P3901 数列找不同
    Luogu 2951 捉迷藏Hide and Seek
    Luogu P1550 打井Watering Hole
    洛谷——P1044 栈
  • 原文地址:https://www.cnblogs.com/evlon/p/956889.html
Copyright © 2011-2022 走看看