freeBuf
主站

分类

漏洞 工具 极客 Web安全 系统安全 网络安全 无线安全 设备/客户端安全 数据安全 安全管理 企业安全 工控安全

特色

头条 人物志 活动 视频 观点 招聘 报告 资讯 区块链安全 标准与合规 容器安全 公开课

官方公众号企业安全新浪微博

FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。

FreeBuf+小程序

FreeBuf+小程序

CRYPTO-RC4加密
2021-10-27 16:45:43

0x0:前言

密码的基础是数学,数学能力往往决定了密码的上限,此篇文章写的是RC4对称加密算法的一些知识。

0x1:RC4

对称加密算法:

v2-57d85bf8d75fa2382a307dc67be6c05c_1440w.png

1.S、T的初始化(可以把T理解为临时数组)

2.数据表S的初始置换

3.密钥流的生成

4.加密

5.解密

v2-dc02f3bc68160d1c846f76607ae4d6b6_1440w.png

选择一个密钥,该密钥是由0到7的数以任意顺序组成,我们把5、6、7作为密钥,该密钥填入T表格中

注意密钥与明文是相同个数的

for(i = 0; i<256;i++)

{

j = (j+s[i]+t[i])%256

}

swap(s[i],s[j])

本质就是s[i]和s[j]的一直交换

计算方法:

当i = 0 时,j=0+0+5

所以就是s[1]和s[5]交换位置

当执行完后,数据表S就会被随机化了

5  4  0  7  1  6  3  2

伪随机数生成算法:

数据表S就可以用来生成随机密钥流序列,从i和j全位0开始:

i=i+1

j=j+s[i]


例子:

i=1

j=0+4 = 4

所以就是s[1]和s[4]置换位置


然后计算t和k

t = s(j)+s(i) = 1+4=5

k=s(5)= 6

0x2:RC4题目讲解

v2-e02f03fd54e3556a786b197a98c8764a_1440w.png

初始化 S (256字节的char型数组),key 是我们自定义的密钥,用来打乱 S ,i 确保 S-box 的每个元素都得到处理, j 保证 S-box 的搅乱是随机的。

void rc4_init(unsigned char*s, unsigned char*key, unsigned long Len){int i = 0, j = 0;char k[256] = { 0 };unsigned char tmp = 0;for (i = 0; i < 256; i++){s[i] = i; // 赋值 Sk[i] = key[i%Len]; // 赋值 K }for (i = 0; i < 256; i++){j = (j + s[i] + k[i]) % 256; // 开始混淆tmp = s[i]; s[i] = s[j]; // 交换s[i]和s[j]s[j] = tmp;}}

加密过程将 S-box 和明文进行 xor 运算,得到密文,解密过程也完全相同

/*加解密*/void rc4_crypt(unsigned char*s, unsigned char*Data, unsigned long Len){int i = 0, j = 0, t = 0;unsigned long k = 0;unsigned char tmp;for (k = 0; k < Len; k++){i = (i + 1) % 256;j = (j + s[i]) % 256;tmp = s[i];s[i] = s[j]; // 交换s[x]和s[y]s[j] = tmp;t = (s[i] + s[j]) % 256;Data[k] ^= s[t];}}

0x3:实现

#include<stdio.h>#include<string.h>typedef unsigned longULONG;/*初始化函数*/void rc4_init(unsigned char*s, unsigned char*key, unsigned long Len){int i = 0, j = 0;char k[256] = { 0 };unsigned char tmp = 0;for (i = 0; i < 256; i++){s[i] = i;k[i] = key[i%Len];}for (i = 0; i < 256; i++){j = (j + s[i] + k[i]) % 256;tmp = s[i];s[i] = s[j]; // 交换s[i]和s[j]s[j] = tmp;}}/*加解密*/void rc4_crypt(unsigned char*s, unsigned char*Data, unsigned long Len){int i = 0, j = 0, t = 0;unsigned long k = 0;unsigned char tmp;for (k = 0; k < Len; k++){i = (i + 1) % 256;j = (j + s[i]) % 256;tmp = s[i];s[i] = s[j]; // 交换s[x]和s[y]s[j] = tmp;t = (s[i] + s[j]) % 256;Data[k] ^= s[t];}}int main(){unsigned char s[256] = { 0 }, s2[256] = { 0 }; // S-boxchar key[256] = { "justfortest" };char pData[512] = "这是一个用来加密的数据Data";unsigned long len = strlen(pData);int i;printf("pData=%s\n", pData);printf("key=%s,length=%d\n\n", key, strlen(key));rc4_init(s, (unsigned char*)key, strlen(key)); // 已经完成了初始化printf("完成对S[i]的初始化,如下:\n\n");for (i = 0; i < 256; i++){printf("%02X", s[i]);if (i && (i + 1) % 16 == 0)putchar('\n');}printf("\n\n");for (i = 0; i < 256; i++) // 用s2[i]暂时保留经过初始化的s[i],很重要的!!!{s2[i] = s[i];}printf("已经初始化,现在加密:\n\n");rc4_crypt(s, (unsigned char*)pData, len); // 加密printf("pData=%s\n\n", pData);printf("已经加密,现在解密:\n\n");rc4_crypt(s2, (unsigned char*)pData, len); // 解密printf("pData=%s\n\n", pData);return 0;}

0x4:题目

v2-e76b4c8d14d38190320324f6f0a13f85_1440w.png

welcometoicqedu

UUyFTj8PCzF6geFn6xgBOYSvVTrbpNU4OF9db9wMcPD1yDbaJw==

# -*- coding: utf-8 -*-import random, base64from hashlib import shadef crypt(data, key):"""RC4 algorithm"""x = 0box = range(256)for i in range(256):x = (x + box[i] + ord(key[i % len(key)])) % 256box[i], box[x] = box[x], box[i]x = y = 0out = []for char in data:x = (x + 1) % 256y = (y + box[x]) % 256box[x], box[y] = box[y], box[x]out.append(chr(ord(char) ^ box[(box[x] + box[y]) % 256]))return ''.join(out)def tencode(data, key, encode=base64.b64encode, salt_length=16):"""RC4 encryption with random salt and final encoding"""salt = ''for n in range(salt_length):salt += chr(random.randrange(256))data = salt + crypt(data, sha1(key + salt).digest())if encode:data = encode(data)return datadef tdecode(data, key, decode=base64.b64decode, salt_length=16):"""RC4 decryption of encoded data"""if decode:data = decode(data)salt = data[:salt_length]return crypt(data[salt_length:], sha1(key + salt).digest(if __name__ == '__main__':# 需要解密的数据data = 'UUyFTj8PCzF6geFn6xgBOYSvVTrbpNU4OF9db9wMcPD1yDbaJw=='# 密钥key = 'welcometoicqedu'# 解码decoded_data = tdecode(data=data, key=key)print("明文是:")print decoded_data

v2-998b58451d4a5fd5c3408711906f99ac_1440w.png

0x5:小结

RC4算法的特点是算法简单,执行速度快。并且密钥长度是可变的,可变范围为1-256字节(8-2048比特),在现在技术支持的前提下,当密钥长度为128比特时,用暴力法搜索密钥已经不太可行,所以能够预见RC4的密钥范围仍然能够在今后相当长的时间里抵御暴力搜索密钥的攻击。实际上,现在也没有找到对于128bit密钥长度的RC4加密算法的有效攻击方法。这也可以说明,密码的长度对于是否能够暴力破解是一个重要的指标。算法、数据结构都是相辅相成的,深入研究下去,就会有成果。

# web安全 # 加密算法 # 加密
本文为 独立观点,未经允许不得转载,授权请联系FreeBuf客服小蜜蜂,微信:freebee2022
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
相关推荐
  • 0 文章数
  • 0 关注者
文章目录