RC4演算法
RC4加密演算法是大名鼎鼎的RSA三人組中的頭號人物Ron Rivest在1987年設計的金鑰長度可變的流加密演算法簇。之所以稱其為簇,是由於其核心部分的S-box長度可為任意,但一般為256位元組。該演算法的速度可以達到DES加密的10倍左右。
RC4演算法的原理很簡單,包括初始化演算法和偽隨機子密碼生成演算法兩大部分。假設S-box長度和金鑰長度均為為n。先來看看演算法的初始化部分(用類C虛擬碼表示):
for (i=0; i<n; i++)
s=i;
j=0;
for (i=0; i<n; i++)
{
j=(j+s+k)%256;
swap(s, s[j]);
}
在初始化的過程中,金鑰的主要功能是將S-box攪亂,i確保S-box的每個元素都得到處理,j保證S-box的攪亂是隨機的。而不同的S-box在經過偽隨機子密碼生成演算法的處理後可以得到不同的子金鑰序列,並且,該序列是隨機的:
i=j=0;
while (明文未結束)
{
++i%=n;
j=(j+s)%n;
swap(s, s[j]);
sub_k=s((s+s[j])%n);
}
得到的子密碼sub_k用以和明文進行xor運算,得到密文,解密過程也完全相同。
由於RC4演算法加密是採用的xor,所以,一旦子金鑰序列出現了重複,密文就有可能被破解。關於如何破解xor加密,請參看Bruce Schneier的Applied Cryptography一書的1.4節Simple XOR,在此我就不細說了。那麼,RC4演算法生成的子金鑰序列是否會出現重複呢?經過我的測試,存在部分弱金鑰,使得子金鑰序列在不到100萬位元組內就發生了完全的重複,如果是部分重複,則可能在不到10萬位元組內就能發生重複,因此,推薦在使用RC4演算法時,必須對加密金鑰進行測試,判斷其是否為弱金鑰。
但在2001年就有以色列科學家指出RC4加密演算法存在著漏洞,這可能對無線通訊網路的安全構成威脅。
以色列魏茨曼研究所和美國思科公司的研究者發現,在使用“有線等效保密規則”(WEP)的無線網路中,在特定情況下,人們可以逆轉RC4演算法的加密過程,獲取金鑰,從而將己加密的資訊解密。實現這一過程並不複雜,只需要使用一臺個人電腦對加密的資料進行分析,經過幾個小時的時間就可以破譯出資訊的全部內容。
專家說,這並不表示所有使用RC4演算法的軟體都容易洩密,但它意味著RC4演算法並不像人們原先認為的那樣安全。這一發現可能促使人們重新設計無線通訊網路,並且使用新的加密演算法
在一些場合,常需要用到一些簡單的加密演算法,這裡的RC4就可以說是最簡單的一種。只要設定一個足夠強的密碼,就可以適用於一些非常簡單的場合了。我是用來加密HTTP傳送的資料的。
RC4函式(加密/解密) 其實,RC4只有加密,將密文再加密一次,就是解密了。
GetKey函式 隨機字串產生器,呵呵,為了方便,大多數加密演算法都有一個隨機密碼產生器,我也就附帶一個了。
ByteToHex函式 把位元組碼轉為十六進位制碼,一個位元組兩個十六進位制。研究發現,十六進位制字串非常適合在HTTP中傳輸,Base64中的某些字元會造成轉義,挺麻煩的。
HexToByte函式 把十六進位制字串,轉為位元組碼。伺服器也按照十六進位制字串的形式把資料傳回來,這裡就可以解碼啦。同時,使用十六進位制字串傳輸,避開了傳輸過程中多國語言的問題。
Encrypt函式 把字串經RC4加密後,再把密文轉為十六進位制字串返回,可直接用於傳輸。
Decrypt函式 直接密碼十六進位制字串密文,再解密,返回字串明文。
原始碼如下:
Encrypt.h檔案:
#ifndef _ENCRYPT_RC4_
#define _ENCRYPT_RC4_
#include <string.h>
#define BOX_LEN 256
int GetKey(const unsigned char* pass, int pass_len, unsigned char *out);
int RC4(const unsigned char* data, int data_len, const unsigned char* key, int key_len, unsigned char* out, int* out_len);
static void swap_byte(unsigned char* a, unsigned char* b);
char* Encrypt(const char* szSource, const char* szPassWord); // 加密,返回加密結果
char* Decrypt(const char* szSource, const char* szPassWord); // 解密,返回解密結果
char* ByteToHex(const unsigned char* vByte, const int vLen); // 把位元組碼pbBuffer轉為十六進位制字串,方便傳輸
unsigned char* HexToByte(const char* szHex); // 把十六進位制字串轉為位元組碼pbBuffer,解碼
#endif // #ifndef _ENCRYPT_RC4_
Encrypt.cpp檔案:
#include "Encrypt.h"
char* Encrypt(const char* szSource, const char* szPassWord) // 加密,返回加密結果
{
if(szSource == NULL || szPassWord == NULL) return NULL;
unsigned char* ret = new unsigned char[strlen(szSource)];
int ret_len = 0;
if(RC4((unsigned char*)szSource,
strlen(szSource),
(unsigned char*)szPassWord,
strlen(szPassWord),
ret,
&ret_len) == NULL)
return NULL;
char* ret2 = ByteToHex(ret, ret_len);
delete[] ret;
return ret2;
}
char* Decrypt(const char* szSource, const char* szPassWord) // 解密,返回解密結果
{
if(szSource == NULL || (strlen(szSource)%2 != 0) || szPassWord == NULL)
return NULL;
unsigned char* src = HexToByte(szSource);
unsigned char* ret = new unsigned char[strlen(szSource) / 2 + 1];
int ret_len = 0;
memset(ret, strlen(szSource) / 2 + 1,0);
if(RC4(src, strlen(szSource) / 2, (unsigned char*)szPassWord, strlen(szPassWord), ret, &ret_len) == NULL)
return NULL;
ret[ret_len] = '';
return (char*)ret;
}
int RC4(const unsigned char* data, int data_len, const unsigned char* key, int key_len, unsigned char* out, int* out_len)
{
if (data == NULL || key == NULL || out == NULL)
return NULL;
unsigned char* mBox = new unsigned char[BOX_LEN];
if(GetKey(key, key_len, mBox) == NULL)
return NULL;
int i=0;
int x=0;
int y=0;
for(int k = 0; k < data_len; k++)
{
x = (x + 1) % BOX_LEN;
y = (mBox[x] + y) % BOX_LEN;
swap_byte(&mBox[x], &mBox[y]);
out[k] = data[k] ^ mBox[(mBox[x] + mBox[y]) % BOX_LEN];
}
*out_len = data_len;
delete[] mBox;
return -1;
}
int GetKey(const unsigned char* pass, int pass_len, unsigned char* out)
{
if(pass == NULL || out == NULL)
return NULL;
int i;
for(i = 0; i < BOX_LEN; i++)
out[i] = i;
int j = 0;
for(i = 0; i < BOX_LEN; i++)
{
j = (pass[i % pass_len] + out[i] + j) % BOX_LEN;
swap_byte(&out[i], &out[j]);
}
return -1;
}
static void swap_byte(unsigned char* a, unsigned char* b)
{
unsigned char swapByte;
swapByte = *a;
*a = *b;
*b = swapByte;
}
// 把位元組碼轉為十六進位制碼,一個位元組兩個十六進位制,內部為字串分配空間
char* ByteToHex(const unsigned char* vByte, const int vLen)
{
if(!vByte)
return NULL;
char* tmp = new char[vLen * 2 + 1]; // 一個位元組兩個十六進位制碼,最後要多一個''
int tmp2;
for (int i=0;i<vLen;i++)
{
tmp2 = (int)(vByte[i])/16;
tmp[i*2] = (char)(tmp2+((tmp2>9)?'A'-10:'0'));
tmp2 = (int)(vByte[i])%16;
tmp[i*2+1] = (char)(tmp2+((tmp2>9)?'A'-10:'0'));
}
tmp[vLen * 2] = '';
return tmp;
}
// 把十六進位制字串,轉為位元組碼,每兩個十六進位制字元作為一個位元組
unsigned char* HexToByte(const char* szHex)
{
if(!szHex)
return NULL;
int iLen = strlen(szHex);
if (iLen<=0 || 0!=iLen%2)
return NULL;
unsigned char* pbBuf = new unsigned char[iLen/2]; // 資料緩衝區
int tmp1, tmp2;
for (int i=0;i<iLen/2;i++)
{
tmp1 = (int)szHex[i*2] - (((int)szHex[i*2]>='A')?'A'-10:'0');
if(tmp1>=16)
return NULL;
tmp2 = (int)szHex[i*2+1] - (((int)szHex[i*2+1]>='A')?'A'-10:'0');
if(tmp2>=16)
return NULL;
pbBuf[i] = (tmp1*16+tmp2);
}
return pbBuf;
}
main.cpp檔案
#include <iostream>
#include <string>
#include <stdio.h>
#include "Encrypt.h"
int main(int argc,char *argv[])
{
int size = 0;
char source[] = "chenli";
char pass[] = "123456";
char *result1 = NULL;
char *result2 = NULL;
result1 = Encrypt(source, pass);
printf("result1=%sn", result1);
result2 = Decrypt(result1, pass);
printf("result2=%sn", result2);
delete []result1;
delete []result2;
return 0;
}
相關文章
- RC4加密解密java演算法加密解密Java演算法
- RC4演算法:流密碼演算法的經典之作演算法密碼
- RC4加密加密
- 【密碼學原理】流密碼和RC4演算法密碼學演算法
- RC4加密演算法在C#中的實現加密演算法C#
- IDA動態除錯解RC4除錯
- SSL/TLS協議安全系列:再見,RC4TLS協議
- Docker 1.6.0 RC4 釋出,Linux 應用容器引擎DockerLinux
- Asprotect1.23 Rc4 之SynchroMagic脫殼修復+破解
- 如何識別新版本的asprotect(包括RC4,0427,0518,0614)
- ASProtect 1.23 RC4 - 1.3.08.24-[Awicons V9.20 ]脫殼AND破解
- 菜鳥脫文 ASProtect 1.23 RC4 ―― DVDFab v1.52,高手免進了
- JavaScript實現線上MD5、SHA、AES、Rabit 、RC4、TripleDES Ripemd160 加密解密工具-toolfk程式設計師線上工具網JavaScript加密解密程式設計師
- 【演算法】KMP演算法演算法KMP
- 演算法-回溯演算法演算法
- 【JAVA演算法】圖論演算法 -- Dijkstra演算法Java演算法圖論
- 演算法(2)KMP演算法演算法KMP
- 【演算法】遞迴演算法演算法遞迴
- 演算法題:洗牌演算法演算法
- [演算法之回溯演算法]演算法
- Manacher演算法、KMP演算法演算法KMP
- 【演算法】KMP演算法解析演算法KMP
- 介面限流演算法:漏桶演算法&令牌桶演算法演算法
- 前端演算法:快速排序演算法前端演算法排序
- 演算法初探--遞迴演算法演算法遞迴
- BP演算法和LMBP演算法演算法
- 隨機演算法 概率演算法隨機演算法
- STL::演算法::常見演算法演算法
- 常用演算法 插值演算法演算法
- 前向分步演算法 && AdaBoost演算法 && 提升樹(GBDT)演算法 && XGBoost演算法演算法
- c/c++ 通用的(泛型)演算法 之 只讀演算法,寫演算法,排序演算法C++泛型演算法排序
- 介面限流演算法:漏桶演算法&令牌桶演算法&redis限流演算法Redis
- 什麼是演算法?如何學習演算法?演算法入門演算法
- 演算法金 | 突破最強演算法模型,決策樹演算法!!演算法模型
- 分類演算法-AdaBoot 演算法演算法boot
- 演算法(八):圖解KNN演算法演算法圖解KNN
- 演算法那些事之冒泡演算法演算法
- 基礎演算法之排序演算法演算法排序