對稱加密算法 之 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;
}

效果拔群:

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM