zoukankan      html  css  js  c++  java
  • 转载并学习实现三重DES加密解密代码(一)

    作者:finallyliuyu 出处:博客园

    声明:此篇博文代码来自于邹德强先生。由于目前找到的版本是残缺版,所以我又进行了补全。读一份好代码,可以领略到作者的编程风格和语言驾驭能力,同时又能从其中汲取养分。现将我所修改后的DES加密解密代码全部张贴出来,有需要的也可以在上面继续改动

    comon.h

    #ifndef _COMMON_H
    #define _COMMON_H
    typedef 
    bool (* PSubKey)[16][48];
    #endif
    myDES.h
    #ifndef _myDES_H
    #define _myDES_H
    #include 
    "common.h"
    #include
    <stdio.h>
    class myDES
    {
    public:
        myDES();
        
    ~myDES();
         
    void ByteToBit(bool *Out, const char *In, int bits);
         
    void BitToByte(char *Out, const bool *In, int bits);
         
    void RotateL(bool *In, int len, int loop);
         
    void RotateR(bool *In,int len,int loop);
         
    void Xor(bool *InA, const bool *InB, int len);
         
    void Transform(bool *Out, bool *In, const char *Table, int len);
         
    void S_func(bool Out[32], const bool In[48]);
         
    void F_func(bool In[32], const bool Ki[48]);
         
    bool RunDes(bool bType,char* In,char* Out,unsigned datalen,const char* Key,const unsigned char keylen);
         
    bool RunPad(int nType,const char* In,unsigned datalen,char* Out,unsigned& padlen);
         
    void SetSubKey(PSubKey pSubKey, const char Key[8]);
         
    void DES(char Out[8], char In[8], const PSubKey pSubKey,bool nType);
         
    bool myRunDES(bool bType,char* In,char* Out,unsigned datalen,const char* Key,const unsigned char keylen);







        
    };
    #endif
    myDES.cpp
    // DES.cpp: implementation of the myDES class.
    //
    //////////////////////////////////////////////////////////////////////
    #include "myDES.h"
    #include 
    "memory.h"


    ////////////////////////////////////////////////////////////////////////
    // initial permutation IP
    const char IP_Table[64= {
        
    585042342618102605244362820124,
            
    625446383022146645648403224168,
            
    574941332517,  91595143352719113,
            
    615345372921135635547393123157
    };
    // final permutation IP^-1 
    const char IPR_Table[64= {
        
    408481656246432397471555236331,
            
    386461454226230375451353216129,
            
    364441252206028353431151195927,
            
    34242105018582633141,  949175725
    };
    // expansion operation matrix
    const char E_Table[48= {
        
    32,  1,  2,  3,  4,  5,  4,  5,  6,  7,  8,  9,
            
    8,  910111213121314151617,
            
    161718192021202122232425,
            
    2425262728292829303132,  1
    };
    // 32-bit permutation function P used on the output of the S-boxes 
    const char P_Table[32= {
        
    1672021291228171,  1523265,  183110,
            
    2,  8241432273,  9,  1913306,  22114,  25
    };
    // permuted choice table (key) 
    const char PC1_Table[56= {
        
    574941332517,  9,  1585042342618,
            
    10,  259514335271911,  360524436,
            
    63554739312315,  7625446383022,
            
    14,  661534537292113,  5282012,  4
    };
    // permuted choice key (table) 
    const char PC2_Table[48= {
        
    14171124,  1,  5,  32815,  62110,
            
    231912,  426,  816,  7272013,  2,
            
    415231374755304051453348,
            
    444939563453464250362932
    };
    // number left rotations of pc1 
    const char LOOP_Table[16= {
        
    1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1
    };
    const char LOOPR_Table[16]={1,2,2,2,2,2,2,1,2,2,2,2,2,2,1,0};
    // The (in)famous S-boxes 
    const char S_Box[8][4][16= {
        
    // S1 
        14,     4,    13,     1,  21511,  8,  310,  612,  5,  9,  0,  7,
            
    015,  7,  414,  213,  110,  61211,  9,  5,  3,  8,
            
    4,  114,  813,  6,  2111512,  9,  7,  310,  5,  0,
            
    1512,  8,  2,  4,  9,  1,  7,  511,  31410,  0,  613,
            
    // S2 
            15,  1,  814,  611,  3,  4,  9,  7,  21312,  0,  510,
            
    313,  4,  715,  2,  81412,  0,  110,  6,  911,  5,
            
    014,  71110,  413,  1,  5,  812,  6,  9,  3,  215,
            
    13,  810,  1,  315,  4,  211,  6,  712,  0,  514,  9,
            
    // S3 
            10,  0,  914,  6,  315,  5,  11312,  711,  4,  2,  8,
            
    13,  7,  0,  9,  3,  4,  610,  2,  8,  514121115,  1,
            
    13,  6,  4,  9,  815,  3,  011,  1,  212,  51014,  7,
            
    11013,  0,  6,  9,  8,  7,  41514,  311,  5,  212,
            
    // S4 
            71314,  3,  0,  6,  910,  1,  2,  8,  51112,  415,
            
    13,  811,  5,  615,  0,  3,  4,  7,  212,  11014,  9,
            
    10,  6,  9,  01211,  71315,  1,  314,  5,  2,  8,  4,
            
    315,  0,  610,  113,  8,  9,  4,  51112,  7,  214,
            
    // S5 
            212,  4,  1,  71011,  6,  8,  5,  31513,  014,  9,
            
    1411,  212,  4,  713,  1,  5,  01510,  3,  9,  8,  6,
            
    4,  2,  1111013,  7,  815,  912,  5,  6,  3,  014,
            
    11,  812,  7,  114,  213,  615,  0,  910,  4,  5,  3,
            
    // S6 
            12,  11015,  9,  2,  6,  8,  013,  3,  414,  7,  511,
            
    1015,  4,  2,  712,  9,  5,  6,  11314,  011,  3,  8,
            
    91415,  5,  2,  812,  3,  7,  0,  410,  11311,  6,
            
    4,  3,  212,  9,  515101114,  1,  7,  6,  0,  813,
            
    // S7 
            411,  21415,  0,  813,  312,  9,  7,  510,  6,  1,
            
    13,  011,  7,  4,  9,  11014,  3,  512,  215,  8,  6,
            
    1,  4111312,  3,  7141015,  6,  8,  0,  5,  9,  2,
            
    61113,  8,  1,  410,  7,  9,  5,  01514,  2,  312,
            
    // S8 
            13,  2,  8,  4,  61511,  110,  9,  314,  5,  012,  7,
            
    11513,  810,  3,  7,  412,  5,  611,  014,  9,  2,
            
    711,  4,  1,  91214,  2,  0,  6101315,  3,  5,  8,
            
    2,  114,  7,  410,  8131512,  9,  0,  3,  5,  611
    };


    myDES::myDES()
    {
        
    }

    myDES::
    ~myDES()
    {
    }

    /*******************************************************************/
    /*
      函 数 名 称:    ByteToBit
      功 能 描 述:    把BYTE转化为Bit流
      参 数 说 明:    Out:    输出的Bit流[in][out]
                    In:        输入的BYTE流[in]
                    bits:    Bit流的长度[in]

      返回值 说明:    void
      作       者:    邹德强
      更 新 日 期:    2003.12.19
    /******************************************************************
    */
    void myDES::ByteToBit(bool *Out, const char *In, int bits)
    {
        
    for(int i=0; i<bits; ++i)
            Out[i] 
    = (In[i>>3]>>(7 - i&7)) & 1;
    }

    /*******************************************************************/
    /*
      函 数 名 称:    BitToByte
      功 能 描 述:    把Bit转化为Byte流
      参 数 说 明:    Out:    输出的BYTE流[in][out]
                    In:        输入的Bit流[in]
                    bits:    Bit流的长度[in]

      返回值 说明:    void
      作       者:    邹德强
      更 新 日 期:    2003.12.19
    /******************************************************************
    */
     
    void myDES:: BitToByte(char *Out, const bool *In, int bits)
    {
        memset(Out, 
    0, bits>>3);
        
    for(int i=0; i<bits; ++i)
            Out[i
    >>3|= In[i]<<(7 - i&7);
    }



    /*******************************************************************/
    /*
      函 数 名 称:    RotateL
      功 能 描 述:    把BIT流按位向左迭代
      参 数 说 明:    In:        输入的Bit流[in]
                    len:    Bit流的长度[in]
                    loop:    向左迭代的长度

      返回值 说明:    void
      作       者:    邹德强
      更 新 日 期:    2003.12.19
    /******************************************************************
    */
     
    void myDES::RotateL(bool *In, int len, int loop)
    {
        
    bool Tmp[256];

        memcpy(Tmp, In, loop);
        memcpy(In, In
    +loop, len-loop);
        memcpy(In
    +len-loop, Tmp, loop);
    }
     
     
    void myDES::RotateR(bool *In,int len,int loop)
     {
         
    bool Tmp[256];
         memcpy(Tmp,In,len
    -loop);
         memcpy(In,In
    +len-loop,loop);
         memcpy(In
    +len-loop,Tmp,len-loop);

     }



    /*******************************************************************/
    /*
      函 数 名 称:    Xor
      功 能 描 述:    把两个Bit流进行异或
      参 数 说 明:    InA:    输入的Bit流[in][out]
                    InB:    输入的Bit流[in]
                    loop:    Bit流的长度

      返回值 说明:    void
      作       者:    邹德强
      更 新 日 期:    2003.12.19
    /******************************************************************
    */
     
    void myDES::Xor(bool *InA, const bool *InB, int len)
    {
        
    for(int i=0; i<len; ++i)
            InA[i] 
    ^= InB[i];
    }


    /*******************************************************************/
    /*
      函 数 名 称:    Transform
      功 能 描 述:    把两个Bit流按表进行位转化
      参 数 说 明:    Out:    输出的Bit流[out]
                    In:        输入的Bit流[in]
                    Table:    转化需要的表指针
                    len:    转化表的长度

      返回值 说明:    void
      作       者:    邹德强
      更 新 日 期:    2003.12.19
    /******************************************************************
    */
     
    void myDES::Transform(bool *Out, bool *In, const char *Table, int len)
    {
        
    bool Tmp[256];

        
    for(int i=0; i<len; ++i)
            Tmp[i] 
    = In[ Table[i]-1 ];
        memcpy(Out, Tmp, len);
    }



    /*******************************************************************/
    /*
      函 数 名 称:    S_func
      功 能 描 述:    实现数据加密S BOX模块
      参 数 说 明:    Out:    输出的32Bit[out]
                    In:        输入的48Bit[in]

      返回值 说明:    void
      作       者:    邹德强
      更 新 日 期:    2003.12.19
    /******************************************************************
    */
     
    void myDES::S_func(bool Out[32], const bool In[48])
    {
        
    for(char i=0,j,k; i<8++i,In+=6,Out+=4
        {
            j 
    = (In[0]<<1+ In[5];
            k 
    = (In[1]<<3+ (In[2]<<2+ (In[3]<<1+ In[4];    //组织SID下标
            
            
    for(int l=0; l<4++l)                                //把相应4bit赋值
                Out[l] = (S_Box[i][j][k]>>(3 - l)) & 1;
        }
    }


    /*******************************************************************/
    /*
      函 数 名 称:    F_func
      功 能 描 述:    实现数据加密到输出P
      参 数 说 明:    Out:    输出的32Bit[out]
                    In:        输入的48Bit[in]

      返回值 说明:    void
      作       者:    邹德强
      更 新 日 期:    2003.12.19
    /******************************************************************
    */
     
    void myDES::F_func(bool In[32], const bool Ki[48])
    {
        
    bool MR[48];
        Transform(MR, In, E_Table, 
    48);
        Xor(MR, Ki, 
    48);
        S_func(In, MR);
        Transform(In, In, P_Table, 
    32);
    }


    /*******************************************************************/
    /*
      函 数 名 称:    RunDes
      功 能 描 述:    执行DES算法对文本加解密
      参 数 说 明:    bType    :类型:加密ENCRYPT,解密DECRYPT
                    bMode    :模式:ECB,CBC
                    In        :待加密串指针
                    Out        :待输出串指针
                    datalen    :待加密串的长度,同时Out的缓冲区大小应大于或者等于datalen
                    Key        :密钥(可为8位,16位,24位)支持3密钥
                    keylen    :密钥长度,多出24位部分将被自动裁减

      返回值 说明:    bool    :是否加密成功
      作       者:    邹德强
      更 新 日 期:    2003.12.19
    /******************************************************************
    */
    bool myDES::RunDes(bool bType,char* In,char* Out,unsigned datalen,const char* Key,const unsigned char keylen)
    {
        
    //判断输入合法性
        if(!(In && Out && Key && datalen && keylen>=8))
            
    return false;
        
    //只处理8的整数倍,不足长度自己填充
        if(datalen & 0x00000007)
            
    return false;
        
        
    bool                m_SubKey[3][16][48];        //秘钥
        
    //构造并生成SubKeys
        unsigned char nKey    =    (keylen>>3)>3 ? 3: (keylen>>3);
        
    for(int i=0;i<nKey;i++)
        {
            SetSubKey(
    &m_SubKey[i],&Key[i<<3]);
        }

            
    //ECB模式
        
            
    if(nKey    ==    1)    //单Key
            {
                
    for(int i=0,j=datalen>>3;i<j;++i,Out+=8,In+=8)
                {
                    DES(Out,In,
    &m_SubKey[0],bType);
                }
            }
            
    else
            
    if(nKey == 2)    //3DES 2Key
            {
                
    for(int i=0,j=datalen>>3;i<j;++i,Out+=8,In+=8)
                {
                    DES(Out,In,
    &m_SubKey[0],bType);
                    DES(Out,Out,
    &m_SubKey[1],!bType);
                    DES(Out,Out,
    &m_SubKey[0],bType);
                }
            }
            
    else            //3DES 3Key
            {
                
    for(int i=0,j=datalen>>3;i<j;++i,Out+=8,In+=8)
                {
                    DES(Out,In,
    &m_SubKey[bType? 2 : 0],bType);
                    DES(Out,Out,
    &m_SubKey[1],!bType);
                    DES(Out,Out,
    &m_SubKey[bType? 0 : 2],bType);    
                }
            }
            
        
        
        
    return true;
    }




    /*******************************************************************/
    /*
      函 数 名 称:    RunPad
      功 能 描 述:    根据协议对加密前的数据进行填充
      参 数 说 明:    bType    :类型:PAD类型
                    In        :数据串指针
                    Out        :填充输出串指针
                    datalen    :数据的长度
                    padlen    :(in,out)输出buffer的长度,填充后的长度

      返回值 说明:    bool    :是否填充成功
      作       者:    邹德强
      修 改 历 史:    

      更 新 日 期:    2003.12.19
    /******************************************************************
    */
    /*bool    myDES::RunPad(int nType,const char* In,unsigned datalen,char* Out,unsigned& padlen)
    {
        int res = (datalen & 0x00000007);
        
        
        if(padlen< (datalen+8-res))
        {
            return false;
        }
        else
        {
            padlen    =    (datalen+8-res);
            memcpy(Out,In,datalen);
            if(nType==PAD_ISO_1)
            {
                memset(Out+datalen,0x00,8-res);
            }

            else if(nType==PAD_ISO_2)
            {
                memset(Out+datalen,0x80,1);
                memset(Out+datalen,0x00,7-res);
            }
            else if(nType==PAD_PKCS_7)
            {
                memset(Out+datalen,8-res,8-res);
            }
            else
            {
                return false;
            }

            return true;
        }
        
        
        
    }
    */
    bool    myDES::RunPad(int nType,const char* In,unsigned datalen,char* Out,unsigned& padlen)
    {
        
    int res = (datalen & 0x00000007);
        memcpy(Out,In,datalen);
        
    if (res)
        {
            memset(Out
    +datalen,0x00,8-res);
            
    return true;

        }
        
    else
        {
            
    return false;
        }


        

                
    }






    //计算并填充子密钥到SubKey数据中
    void myDES::SetSubKey(PSubKey pSubKey, const char Key[8])
    {
        
    bool K[64], *KL=&K[0], *KR=&K[28];
        ByteToBit(K, Key, 
    64);
        Transform(K, K, PC1_Table, 
    56);
        
    for(int i=0; i<16++i) 
        {
            
            
                RotateL(KL, 
    28, LOOP_Table[i]);
                RotateL(KR, 
    28, LOOP_Table[i]);    
               Transform((
    *pSubKey)[i], K, PC2_Table, 48);
        }
    }



    //DES单元运算
    void myDES::DES(char Out[8], char In[8], const PSubKey pSubKey,bool nType)
    {
        
    bool M[64], tmp[32], *Li=&M[0], *Ri=&M[32];
        ByteToBit(M, In, 
    64);
        Transform(M, M, IP_Table, 
    64);
        
    if( nType )
        {
            
    for(int i=0; i<16++i)
            {
                memcpy(tmp, Ri, 
    32);        //Ri[i-1] 保存
                F_func(Ri, (*pSubKey)[i]);    //Ri[i-1]经过转化和SBox输出为P
                Xor(Ri, Li, 32);            //Ri[i] = P XOR Li[i-1]
                memcpy(Li, tmp, 32);        //Li[i] = Ri[i-1]
            }
        }
        
    else
        {
            
    for(int i=15; i>=0--i) 
            {
                memcpy(tmp, Ri, 
    32);        //Ri[i-1] 保存
                F_func(Ri, (*pSubKey)[i]);    //Ri[i-1]经过转化和SBox输出为P
                Xor(Ri, Li, 32);            //Ri[i] = P XOR Li[i-1]
                memcpy(Li, tmp, 32);        //Li[i] = Ri[i-1]
            }
        }
        RotateL(M,
    64,32);                    //Ri与Li换位重组M
        Transform(M, M, IPR_Table, 64);        //最后结果进行转化
        BitToByte(Out, M, 64);                //组织成字符
    }
    bool myDES::myRunDES(bool bType,char* In,char* Out,unsigned datalen,const char* Key,const unsigned char keylen)
    {


        
    return true;
        
    }
  • 相关阅读:
    JQuery的js写法
    Reapter 中客户端控件和服务器端控件的选择
    ASP.NET 中随时向页面输入数据
    SQL补充查询
    repeater项模版bottom事件获取该bottom所在行id为lblName的label控件的text
    微软Visual Studio 2010架构设计功能应用
    动态表格
    如何选中jsTree中已checked的Item的信息
    据说看完这21个故事的人,30岁前都成了亿万富翁。你是下一个吗?
    WebSocket编解码器
  • 原文地址:https://www.cnblogs.com/finallyliuyu/p/1917600.html
Copyright © 2011-2022 走看看