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 doS[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 doj= (j + S[i] + T[i]) mod 256swap(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<RC4_KEY> B<key> using the B<len> bytes long key atB<data>.

2. RC4: encrypts or decrypts the B<len>bytes of data at B<indata> using B<key> and places the result atB<outdata>.  Repeated RC4() callswith the same B<key> yield a continuous key stream. Since RC4 is a streamcipher (the input is XORed with a pseudo-random key stream to produce theoutput), decryption uses the same function calls as encryption.

以下是测试代码:

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);
}} // namespaceint 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<unsigned char[]> ciphertext(new unsigned char[length]);RC4_Encrypt((const unsigned char*)cleartext_encode, length, key, ciphertext.get());std::unique_ptr<unsigned char[]> 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

对称加密算法之RC4介绍及OpenSSL中RC4常用函数使用举例相关推荐

  1. 非对称加密算法之RSA介绍及OpenSSL中RSA常用函数使用举例

    RSA算法,在1977年由Ron Rivest.Adi Shamirh和LenAdleman,在美国的麻省理工学院开发完成.这个算法的名字,来源于三位开发者的名字.RSA已经成为公钥数据加密标准. R ...

  2. 对称加密算法AES简介及在OpenSSL中使用举例

    高级加密标准(AES, Advanced Encryption Standard)由美国国家标准和技术协会(NIST)于2000年公布,它是一种对称加密算法,用来替代DES.AES也称为Rijndae ...

  3. mysqlsql常用函数_MySQL中的常用函数

    在MySQL中,函数不仅可以出现在select语句及其子句中,而且还可以出现在update.delete语句中. 常用的函数有: 1. 字符串函数:主要用于处理字符串. 2. 数值函数:主要用于处理数 ...

  4. php源码十六进制加密,php-简单对称加密算法和字符串与十六进制之间的互转函数,php-十六进制_PHP教程...

    php-简单对称加密算法和字符串与十六进制之间的互转函数,php-十六进制 /** * 简单对称加密算法之加密 * @param String $string 需要加密的字串 * @param Str ...

  5. php spl函数,PHP SPL标准库中的常用函数介绍

    这篇文章主要介绍了PHP SPL标准库中的常用函数介绍,本文着重讲解了spl_autoload_extensions().spl_autoload_register().spl_autoload()三 ...

  6. C++STL中string的头文件中的常用函数

    文章目录 STL简介 头文件 初始化操作 实现效果 基本函数 1.size,length,capacity 2.resize,reserve 1,2的实现代码 实现效果 3.at,append,ins ...

  7. python scipy.stats.norm.cdf_python的scipy.stats模块中正态分布常用函数总结

    python的scipy.stats模块是连续型随机变量的公共方法,可以产生随机数,通常是以正态分布作为scipy.stats的基本使用方法.本文介绍正态分布的两种常用函数:1.累积概率密度函数sta ...

  8. Python之pandas:pandas中数据处理常用函数(与空值相关/去重和替代)简介、具体案例、使用方法之详细攻略

    Python之pandas:pandas中数据处理常用函数(与空值相关/去重和替代)简介.具体案例.使用方法之详细攻略 目录 pandas中数据处理常用函数(isnull/dropna/fillna/ ...

  9. c语言中math的库函数,C语言中math.h库中的常用函数

    C语言中math.h库中的常用函数 int abs(int i) 返回整型参数i的绝对值 double cabs(struct complex znum) 返回复数znum的绝对值 double fa ...

最新文章

  1. CTFshow 命令执行 web65
  2. c语言status显示done6,Netbackup Done status 6 解决方法
  3. 交叉验证技术(part1)--概述
  4. java程序猿面试问缺点怎么回答_JAVA程序员面试32问,你能回答多少题
  5. python爬虫——与不断变化的页面死磕和更新换代(3)
  6. 3.深入分布式缓存:从原理到实践 --- 动手写缓存
  7. SQL Server 2005安装时提示“服务无法启动”
  8. IDEA+EmmyLua Lua开发环境搭建
  9. 蒙泰卡罗模应用实例之买书问题
  10. PID到底是个啥?来给你讲个故事
  11. 安装oh my zsh后出现的目录权限问题
  12. python 实现excel单元格合并和导出
  13. Shellshock漏洞复现
  14. Uniapp返回上一页触发页面更新
  15. Tomcat过时了?别多想,很多公司还是在用的。这份Tomcat架构详解,真的颠覆你的认知
  16. 手把手教你在阿里云服务器上安装Java环境(图文教程)
  17. Matlab--蒙特卡洛方法求pi值
  18. python学习笔记:插入函数append,extend与insert的使用与区别
  19. Apple Pay支付分享
  20. 11.2、SR基本原理

热门文章

  1. 物联网协议对比(HTTP、websocket、XMPP、COAP、MQTT和DDS协议)
  2. 数据结构与算法(5)字符串(BF算法、KMP算法及KMP算法优化)
  3. Image deformation of AffineSimilarityRigidProjective
  4. 在WebStorm里面搜索文件中出现的中文字符
  5. push代码到github时,每次都要输入用户名和密码的问题
  6. GameMaker Studio从头开始学习设计和开发3款游戏
  7. Linux进程描述符task_struct结构体简析
  8. python_2开发简单爬虫
  9. vue 在浏览器控制台怎么调试 谷歌插件vue Devtools
  10. iOS开发网络篇—HTTP协议