RC4是一种对称密码算法,它属于对称密码算法中的序列密码(streamcipher,也称为流密码),它是可变密钥长度,面向字节操作的流密码。
RC4是流密码streamcipher中的一种,为序列密码。RC4加密算法是Ron Rivest在1987年设计出的密钥长度可变的加密算法簇。起初该算法是商业机密,直到1994年,它才公诸于众。由于RC4具有算法简单,运算速度快,软硬件实现都十分容易等优点,使其在一些协议和标准里得到了广泛应用。
流密码也属于对称密码,但与分组加密算法不同的是,流密码不对明文数据进行分组,而是用密钥生成与明文一样长短的密码流对明文进行加密,加解密使用相同的密钥。
RC4算法特点:(1)、算法简洁易于软件实现,加密速度快,安全性比较高;(2)、密钥长度可变,一般用256个字节。
对称密码的工作方式有四种:电子密码本(ECB, electronic codebook)方式、密码分组链接(CBC, cipherblock chaining)方式、密文反馈(CFB, cipher-feedback)方式、输出反馈(OFB, output-feedback)方式。
RC4算法采用的是输出反馈工作方式,所以可以用一个短的密钥产生一个相对较长的密钥序列。
OFB方式的最大的优点是消息如果发生错误(这里指的是消息的某一位发生了改变,而不是消息的某一位丢失),错误不会传递到产生的密钥序列上;缺点是对插入攻击很敏感,并且对同步的要求比较高。
RC4的执行速度相当快,它大约是分块密码算法DES的5倍,是3DES的15倍,且比高级加密算法AES也快很多。RC4算法简单,实现容易。RC4的安全保证主要在于输入密钥的产生途径,只要在这方面不出现漏洞,采用128bit的密钥是非常安全的。
RC4算法加密流程:包括密钥调度算法KSA和伪随机子密码生成算法PRGA两大部分(以密钥长度为256个字节为例)。
密钥调度算法:首先初始化状态矢量S,矢量S中元素的值被按升序从0到255排列,即S[0]=00, S[1]=1, …, S[255]=255.同时建立一个临时矢量T,如果密钥K的长度为256字节,则将K赋给T。否则,若密钥长度为keylen字节,则将K的值赋给T的前keylen个元素,并循环重复用K的值赋给T剩下的元素,直到T的所有元素都被赋值。这些预操作可概括如下:
/*初始化*/
for i = 0 to 255 do
S[i]= i;
T[i]= K[i mod keylen];
然后用T产生S的初始置换,从S[0]到S[255],对每个S[i],根据由T[i]确定的方案,将S[i]置换为S中的另一字节:
/*S的初始序列*/
j= 0
for i = 0 to 255 do
j= (j + S[i] + T[i]) mod 256
swap(S[i],S[j]);
因为对S的操作仅是交换,所以惟一的改变就是顺序的改变。S仍然包含从0到255的所有元素,在初始化的过程中,密钥的主要功能是将S-box搅乱,代码中的变量i确保S-box的每个元素都得到处理,变量j保证S-box的搅乱是随机的。因此不同的S-box在经过伪随机子密码生成算法的处理后可以得到不同的子密钥序列,并且该序列是随机的。
伪随机序列生成算法:矢量S一旦完成初始化,输入密钥就不再被使用。密钥流的生成是从S[0]到S[255],对每个S[i],根据当前S的值,将S[i]与S中的另一字节置换。当S[255]完成置换后,操作继续重复,从S[0]开始:
/*密钥流的产生*/
i,j = 0;
while(true)
i= (i + 1) mod 256;
j= (j + S[i]) mod 256;
swap(S[i],S[j]);
t= (S[i] + s[j]) mod 256;
k= S[t]
伪随机序列一旦生成,就得到子密码sub_k,把子密钥和明文进行异或运算,得到密文。解密过程也完全相同。加密中,只需将k的值与下一明文字节异或;相反解密中,将k的值与下一密文字节异或就可以还原出明文信息。算法描述为:
for(i = 0; i < textlength; i ++)
ciphertext[i]= keystream[i] ^ plaintext[i]
RC4算法存在的问题:因为RC4算法具有实现简单,加密速度快,对硬件资源耗费低等优点,使其跻身于轻量级加密算法的行列。但是其简单的算法结构也容易遭到破解攻击,RC4算法的加密强度完全取决于密钥,即伪随机序列生成,而真正的随机序列是不可能实现,只能实现伪随机。这就不可避免出现密钥的重复。RC4算法不管是加密还是解密,都只进行了异或运算,这就意味着,一旦子密钥序列出现了重复,密文就极有可能被破解。
具体破解过程如下:若明文、密钥是任意长的字节,可以用重合码计数法(counting coincidence)找出密钥长度。把密文进行各种字节的位移,并与原密文进行异或运算,统计那些相同的字节。如果位移是密钥长度的倍数,那么超过60%的字节将是相同的;如果不是,则至多只有0.4%的字节是相同的,这叫做重合指数(index of coincidence)。找出密钥长度倍数的最小位移,按此长度移到密文,并且和自身异或。由于明文每字节有1.3位的实际信息,因此有足够的冗余度去确定位移的解密。对所有的密钥,输出密钥流的前几个字节不是随机的,因此极有可能会泄露密钥的信息。如果一个长期使用的密钥与一个随机数串联产生RC4算法密钥,那么可以通过分析大量由该密钥加密的密文得到这个长期使用的密钥。解决该问题的办法是:抛弃密钥流最初的那部分数据。
RC4is a stream cipher with variable key length. Typically, 128 bit (16 byte) keys are used for strong encryption, butshorter insecure key sizes have been widely used due to export restrictions.
1. RC4_set_key:sets up theB
2. RC4: encrypts or decrypts the B
以下是测试代码:
namespace {
void RC4_Encrypt(const unsigned char* cleartext, int length, const std::string& key, unsigned char* ciphertext)
{
RC4_KEY rc4key;
RC4_set_key(&rc4key, key.length(), (const unsigned char*)key.c_str());
RC4(&rc4key, length, cleartext, ciphertext);
}
void RC4_Decrypt(const unsigned char* ciphertext, int length, const std::string& key, unsigned char* cleartext)
{
RC4_KEY rc4key;
RC4_set_key(&rc4key, key.length(), (const unsigned char*)key.c_str());
RC4(&rc4key, length, ciphertext, cleartext);
}
} // namespace
int test_openssl_rc4()
{
const std::string cleartext = "中国北京12345$abcde%ABCDE@!!!!";
const std::string key = "beijingchina1234567890ABCDEFGH!!!";
char* cleartext_encode = b64_encode((const unsigned char*)cleartext.c_str(), cleartext.length());
int length = strlen(cleartext_encode);
fprintf(stdout, "cleartext encode length: %d\n", length);
std::unique_ptr ciphertext(new unsigned char[length]);
RC4_Encrypt((const unsigned char*)cleartext_encode, length, key, ciphertext.get());
std::unique_ptr decrypt(new unsigned char[length]);
RC4_Decrypt(ciphertext.get(), length, key, decrypt.get());
unsigned char* ciphertext_decode = b64_decode((char*)decrypt.get(), length);
fprintf(stdout, "src cleartext: %s\n", cleartext.c_str());
fprintf(stdout, "genarate ciphertext: %s\n", ciphertext.get());
fprintf(stdout, "dst cleartext: %s\n", ciphertext_decode);
int ret = 0;
if (strcmp(cleartext.c_str(), (const char*)ciphertext_decode) == 0) {
fprintf(stdout, "RC4 decrypt success\n");
} else {
fprintf(stderr, "RC4 decrypt fail\n");
ret = -1;
}
free(cleartext_encode);
free(ciphertext_decode);
return ret;
}
执行结果如下:
RC4理论摘自:《RFID中轻量级加密算法及实现技术的研究》
GitHub:https://github.com/fengbingchun/OpenSSL_Test