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