Alleged RC4密码算法分析与实现
2017-07-20 19:17
330 查看
Alleged RC4密码算法即所谓RC4密码算法,由RSA算法(Ronald Rivest,Adi Shamir,Leonard Adleman)发明者之一的Ronald Rivest设计。RC4之所以加上Alleged是起初在RSADSI(RSA数据安全有限公司),该算法是被保密的,想要了解该算法的细节需要与其签署保密协议后才能得到。但是后来,该算法被匿名公开,并迅速传遍全世界的FTP网点,最后在密码学课上被讲解。而RSADSI却从未正式公布该算法,并且宣称即使代码公开,它依旧是商业机密。这也就是为什么说它也叫Alleged RC4(所谓的RC4)。
①初始化算法(Key-scheduling algorithm ,KSA)
②伪随机子生成算法(Pseudo-random generation algorithm ,PRGA)
伪随机子k是由初始化的S向量所生成的。
(1)、初始化算法:
首先RC4以OFB模式(Output-Feedback,输出反馈模式)工作:即所谓初始化向量加密后与明文分组直接异或得到密文分组(密钥序列和明文序列独立)。但是由于RC4和DES不同,DES的分组是64bit即8字节为一组,而RC4是以8bit为一组,即以字节流方式进行加密(流密码)。而初始化向量IV(Initialization Vector)是一个长度为256的单字节数组S。S的初始化是0~255的索引直接赋给索引到的内存,即线性填充::
for i from 0 to 255
S[i] = i;
然后用可变长度的密钥(40~2048 bits,即最小5字节最大256字节),填充另一个256字节的数组K。由于密钥长度不一定为256字节,所以不断重复密钥,直至填满256字节的K数组:
for i from 0 to 255
K[i] = key[i] % len; //len = strlen(key);
最后用两个计数器进行S盒的混乱置换:
for i from o to 255
j = (j + S[i] + K[i]) mod 256; //key不一样则K[i]不同,j也就不同
swap(S[i],S[j]); //置换,打乱原有线性规律
完成以上三步,向量S(S盒)就初始化完毕了。初始化S其实就是将Key密钥经过运算分散到S盒中去,并打乱原有S盒顺序(i保证每个元素的改变、j保证元素随机(伪随机)的改变),不同密钥就对应不同的S盒。
(2)、伪随机子生成算法:
有了S向量,就可以进行加密操作了,加密操作只是对明文字节流和向量生成的伪随机算子进行异或操作就得到密文流。而伪随机算子的产生算法如下(注意i和j是计数器,不是数组向量的索引):
len = strlen(plaintext); //明文的长度
i = 0, j = 0; //计数器i和j初始化为0
for n from 0 to len
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]; //得伪到随机算子
伪随机算子字节K与明文一个字节异或得到密文字节,循环len次则明文加密完毕。解密则是K与密文的异或得到明文(Plaintext ⊕ K = Ciphertext, Ciphertext ⊕ K = Plaintext)。
由于RC4算法的结构简单,分析过程和编码过程基本相差无几。代码如下:
(2)测试:
不同密钥得出的加密结果的密文流不同:
参考资料:《应用密码学–协议算法与C源程序》[美]Bruce Schneier著 ,机械工业出版社。
1、RC4算法的细节:
RC4算法包括两部分:①初始化算法(Key-scheduling algorithm ,KSA)
②伪随机子生成算法(Pseudo-random generation algorithm ,PRGA)
伪随机子k是由初始化的S向量所生成的。
(1)、初始化算法:
首先RC4以OFB模式(Output-Feedback,输出反馈模式)工作:即所谓初始化向量加密后与明文分组直接异或得到密文分组(密钥序列和明文序列独立)。但是由于RC4和DES不同,DES的分组是64bit即8字节为一组,而RC4是以8bit为一组,即以字节流方式进行加密(流密码)。而初始化向量IV(Initialization Vector)是一个长度为256的单字节数组S。S的初始化是0~255的索引直接赋给索引到的内存,即线性填充::
for i from 0 to 255
S[i] = i;
然后用可变长度的密钥(40~2048 bits,即最小5字节最大256字节),填充另一个256字节的数组K。由于密钥长度不一定为256字节,所以不断重复密钥,直至填满256字节的K数组:
for i from 0 to 255
K[i] = key[i] % len; //len = strlen(key);
最后用两个计数器进行S盒的混乱置换:
for i from o to 255
j = (j + S[i] + K[i]) mod 256; //key不一样则K[i]不同,j也就不同
swap(S[i],S[j]); //置换,打乱原有线性规律
完成以上三步,向量S(S盒)就初始化完毕了。初始化S其实就是将Key密钥经过运算分散到S盒中去,并打乱原有S盒顺序(i保证每个元素的改变、j保证元素随机(伪随机)的改变),不同密钥就对应不同的S盒。
(2)、伪随机子生成算法:
有了S向量,就可以进行加密操作了,加密操作只是对明文字节流和向量生成的伪随机算子进行异或操作就得到密文流。而伪随机算子的产生算法如下(注意i和j是计数器,不是数组向量的索引):
len = strlen(plaintext); //明文的长度
i = 0, j = 0; //计数器i和j初始化为0
for n from 0 to len
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]; //得伪到随机算子
伪随机算子字节K与明文一个字节异或得到密文字节,循环len次则明文加密完毕。解密则是K与密文的异或得到明文(Plaintext ⊕ K = Ciphertext, Ciphertext ⊕ K = Plaintext)。
2、RC4代码实现与测试:
(1)算法实现:由于RC4算法的结构简单,分析过程和编码过程基本相差无几。代码如下:
#include "rc4.h" void rc4_algorithm(unsigned char * data, unsigned char * key) { unsigned char s[256] = {0};//向量(S盒) size_t len_data = strlen((const char *)data); size_t len_key = strlen((const char *)key); vector_init(s, key, len_key);//先根据key密钥初始化向量 encrypt(s, data, len_data);//再用初始化的向量对data数据加密 } //初始化向量 void vector_init(unsigned char *s, unsigned char *key, size_t len) { int i = 0, j = 0; unsigned char k[256] = {0}; for(i = 0; i < 256; i++){ s[i] = i; k[i] = key[i % len]; } //使线性的向量经过key的变换处理为非线性 for(i = 0; i < 256; i++){ j = (j + s[i] + k[i]) % 256; swap(&s[i],&s[j]); } } void encrypt(unsigned char *s, unsigned char *data, size_t len) { size_t i = 0, j = 0, n = 0, t = 0; for(n = 0; n < len; n++){ i = (i + 1) % 256; j = (j + s[i]) % 256; swap(&s[i], &s[j]); t = (s[i] + s[j]) % 256; data ^= s[t];//字节流异或加密 } } void swap(unsigned char * a, unsigned char * b) { // *a ^= *b ^= *a ^= *b;//注意:种做法有一个弊端。当a和b是一块内存,则该内存的值经过交换操作后被置为0 unsigned char temp; temp = *a; *a = *b; *b = temp; }
(2)测试:
/* *Author:Kangruojin *Time:2017年7月20日15:11:28 *Mail:mailbox_krj@163.com *versionL:v1.1 */ #include "rc4.h" int main(int argc, char * argv[]) { unsigned char message[] = "I love you!"; //打印明文字符串与明文字节流 printf("明文:%s\n",message); int len = strlen((const char*)message); for(int i = 0; i < len; i++){ printf("%02x",message[i]); } printf("\n"); //打印密文字符串与密文字节流 rc4_algorithm(message, (unsigned char *)argv[1]); printf("秘文:%s\n",message); for(int i = 0; i < len; i++){ printf("%02x",message[i]); } printf("\n"); //打印解密后明文字符串与明文字节流 rc4_algorithm(message, (unsigned char *)argv[1]); printf("明文:%s\n",message); for(int i = 0; i < len; i++){ printf("%02x",message[i]); } printf("\n"); return 0; }
不同密钥得出的加密结果的密文流不同:
参考资料:《应用密码学–协议算法与C源程序》[美]Bruce Schneier著 ,机械工业出版社。
相关文章推荐
- 基于规则评分的密码强度检测算法分析及实现(JavaScript)
- 密码强度检测算法分析及实现(JavaScript)案例说明
- MD5密码算法分析与实现
- 基于规则评分的密码强度检测算法分析及实现(JavaScript)
- 基于规则评分的密码强度检测算法分析及实现(JavaScript)
- LRU缓存淘汰算法分析与实现
- 爬山算法与模拟退火算法的分析与实现
- [Java算法分析与设计]线性结构与顺序表(List)的实现应用
- 通过分析 JDK 源代码研究 TreeMap 红黑树算法实现
- Hoare选择算法 寻找第k小元素C实现 算法的“AWK脚手架和grap运行过程分析”
- PHP实现的登录,注册及密码修改功能分析
- Levenshtein Distance算法实现简单文本相似度分析
- 对Weka中DBSCAN算法的分析以及在C#中的实现
- JavaScript实现维吉尼亚(Vigenere)密码算法实例
- 求两个数组的交集、并集和差集算法分析与实现(转自http://blog.sina.com.cn/s/blog_616e189f0100mrdn.html)
- 编译原理之算术表达式的词法分析算法c实现
- AdaBoost算法分析与实现
- 循环冗余校验 CRC 的算法分析和程序实现
- DES, RC4, RC5, AES, RSA, MD5, SHA1 安全算法分析
- 最短路径算法—Bellman-Ford(贝尔曼-福特)算法分析与实现(C/C++)