• 对称加密算法 之 RC4流密码


    RC4生成一种称为密钥流的伪随机流,它同明文通过异或操作相混合以达到加密的目的,解密时,同密文进行异或操作。其密钥流的生成由两部分组成:KSA和PRGA。

                                                                                          --《加密与解密》

    这里我们拿实例程序RC4Sample作分析,首先定义一个结构体rc4_state

    struct rc4_state
    {
        int x, y, m[256];
    };

    再来查看程序中的加密关键代码:

    BOOL GenerateSerial(HWND hWnd) 
    {
        TCHAR szName[MAXINPUTLEN]={0};
        TCHAR szSerial[MAXINPUTLEN]={0};
        TCHAR szBuffer[MAXINPUTLEN]={0};
        BYTE rc4_key[8]={0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF};        
        struct rc4_state rc4_test;
        int dtLength,i;
    
        dtLength=GetDlgItemText(hWnd, IDC_Name, szName, sizeof(szName)/sizeof(TCHAR)+1);  //获取字符串
        if (dtLength==0)                                        //如果为空
        {
            SetDlgItemText(hWnd, IDC_Serial, "please input name");
            return FALSE;
        }
        
        memset(&rc4_test,0,sizeof(rc4_test));        //用0填充结构体
        rc4_setup(&rc4_test,rc4_key,8);                //密钥调度算法(KSA)
        rc4_crypt(&rc4_test,szName,dtLength);        //PRGA
    
        for (i=0;i<dtLength;i++)
        {
            sprintf((szSerial+i*2),"%02X",(BYTE)szName[i]);        //以十六进制形式输出,空位前面补0
        }
        
        SetDlgItemText(hWnd, IDC_Serial,szSerial); 
        /* this is decrypt 
         * use it by yourself
    
        memset(&rc4_test,0,sizeof(rc4_test));
        rc4_setup(&rc4_test,rc4_key,8);
        rc4_crypt(&rc4_test,szName,dtLength);
        
        */
        return TRUE;
    }

    分析流程可知,进行加密操作的函数是:rc4_setup、rc4_crypt。也就是上面所说的KSA 和 PRGA。

    结构体中的m数组将用来存储密钥流,首先rc4_setup函数采用8个字节的密钥来对密钥流数组进行替换:

    void rc4_setup( struct rc4_state *s, unsigned char *key,  int length )        //密钥调度算法
    {
        int i, j, k, *m, a;
    
        s->x = 0;
        s->y = 0; 
        m = s->m;
    
        for( i = 0; i < 256; i++ )            //用0-255初始化数组
        {
            m[i] = i;
        }
    
        j = k = 0;
    
        for( i = 0; i < 256; i++ )
        { 
            a = m[i];
            j = (unsigned char) ( j + a + key[k] );
            m[i] = m[j]; m[j] = a;
            if( ++k >= length ) k = 0;        //k大于key长度则回到数组开头
        }
    }

    然后在rc4_crypt中进行加密操作,先将密钥流数组进行一轮置换,再将得出的子密钥和明文进行异或:

    void rc4_crypt( struct rc4_state *s, unsigned char *data, int length )
    { 
        int i, x, y, *m, a, b;
    
        x = s->x;
        y = s->y;
        m = s->m;
    
        for( i = 0; i < length; i++ )
        {
            x = (unsigned char) ( x + 1 ); a = m[x];
            y = (unsigned char) ( y + a );
            m[x] = b = m[y];
            m[y] = a;                                    //将m[x]的值与m[y]的值进行置换
            data[i] ^= m[(unsigned char) ( a + b )];    //得到的子密钥与明文进行异或运算
        }
    
        s->x = x;
        s->y = y;
    }

    效果拔群:

      

    我们一路奋战,不是为了改变世界,而是不让世界改变我们 ——《熔炉》
  • 相关阅读:
    [CF1398A-E] Codeforces Round 93
    bzoj3758 数数和bzoj3798 特殊的质数
    P4234 最小差值生成树
    [UOJ274] P6664 温暖会指引我们前行
    P4172 [WC2006]水管局长
    bzoj2959 长跑
    bzoj4998 星球联盟(lct+并查集维护动态双连通性)
    P1501 [国家集训队]Tree II
    link-cut-tree
    fhq-treap,splay 模板
  • 原文地址:https://www.cnblogs.com/ZRBYYXDM/p/5005814.html
Copyright © 2020-2023  润新知