对称加密算法 之 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;
}

效果拔群:

  

我们一路奋战,不是为了改变世界,而是不让世界改变我们 ——《熔炉》
原文地址:https://www.cnblogs.com/ZRBYYXDM/p/5005814.html