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; }
效果拔群:

