学习RC4及C语言手搓RC4算法

本文主要是了解RC4和清楚RC4步骤。重点是算法步骤。 了解RC4 RC4(Rivest Cipher 4)是一种流加密算法,由Ron Rivest在1987年设计。 它通过生成密钥流字节与明文进行异或操作来实现加密,它加解密使用相同的密钥,因此也属于对称加密算法。 RC4使用可变长度的密钥,长度范围为1到256个字节。 RC4算法主要代码是如何生成密钥流。 分为两步: 初始化阶段 KSA(Key-Scheduling Algorithm) 密钥流生成阶段 PRGA (pseudo-random generation algorithm) KSA主要步骤如下: 初始化 S 盒:创建一个256长度的数组S,初始化为S[i] = i 初始化临时数组 T进行密钥填充:如果RC4密钥(key)长度为key_len,密钥重复填充到长度为 256 的数组 T 中, T[i] = key[ i % key_len] 打乱 S 盒:使用密钥对 S 盒进行置换。 伪代码: for i from 0 to 255: S[i] = i T[i] = key[i % key_len] j = 0 for i from 0 to 255: j = (j + S[i] + T[i]) % 256 swap(S[i], S[j]) PRGA主要步骤如下: 密钥流生成阶段的目的是生成伪随机的密钥流字节,用于与明文或密文进行异或操作。 伪代码如下: i = 0, j = 0 while (需要生成密钥流字节长度): i = (i + 1) % 256 j = (j + S[i]) % 256 swap(S[i], S[j]) k = S[(S[i] + S[j]) % 256] 输出 k k就是密钥流字节。这是一个字节。这个字节用于和明文异或。 我生成一个数组keystream存储密钥流字节,这个keystream应该是和明文长度一致的。加解密的时候按字节进行异或。 我写的简单代码。 #include <stdio.h> #include <string.h> // 将字符数组转换为十六进制格式并打印 void charArrayToHex(const unsigned char *array, int length) { for (int i = 0; i < length; i++) { printf("%02X ", array[i]); } printf("\n"); } int main() { // 密钥和明文 unsigned char key[] = "secret"; unsigned char plaintext[] = "flag{Congratulation!}"; // 计算密钥和明文的长度 int key_len = strlen((char *)key); int plaintext_len = strlen((char *)plaintext); // 输出密钥和明文信息 printf("加密明文: %s\n", plaintext); printf("密钥: %s\n", key); printf("密钥长度: %d\n", key_len); printf("明文长度: %d\n", plaintext_len); // 初始化变量 unsigned char ciphertext[256] = {0}; // 密文 unsigned char decryptedtext[256] = {0}; // 解密后的明文 unsigned char S[256]; // S盒 unsigned char T[256]; // 临时数组 unsigned char keystream[256] = {0}; // 密钥流 // KSA阶段(Key-Scheduling Algorithm) printf("KSA阶段...\n"); for (int i = 0; i < 256; i++) { S[i] = i; // 初始化S盒 T[i] = key[i % key_len]; // 用密钥填充T数组 } int j = 0; for (int i = 0; i < 256; i++) { j = (j + S[i] + T[i]) % 256; // 打乱S盒 unsigned char temp = S[i]; S[i] = S[j]; S[j] = temp; } printf("KSA阶段完成!\n"); // PRGA阶段(Pseudo-Random Generation Algorithm) printf("PRGA阶段...\n"); int i = 0; j = 0; for (int k = 0; k < plaintext_len; k++) { i = (i + 1) % 256; j = (j + S[i]) % 256; unsigned char temp = S[i]; S[i] = S[j]; S[j] = temp; keystream[k] = S[(S[i] + S[j]) % 256]; // 生成密钥流 } printf("PRGA阶段完成!\n"); // 加密阶段 printf("加密阶段...\n"); for (int k = 0; k < plaintext_len; k++) { ciphertext[k] = plaintext[k] ^ keystream[k]; // 异或操作加密 } printf("加密完成! 密文: "); charArrayToHex(ciphertext, plaintext_len); // 输出密文的十六进制 // 解密阶段 printf("解密阶段...\n"); for (int k = 0; k < plaintext_len; k++) { decryptedtext[k] = ciphertext[k] ^ keystream[k]; // 异或操作解密 } printf("解密完成! 明文: %s\n", decryptedtext); // 输出解密后的明文 printf("明文 HEX: "); charArrayToHex(decryptedtext, plaintext_len); // 输出明文的十六进制 return 0; } ...

February 3, 2025 · 4 min · Yalois

古典密码-仿射密码学习

仿射密码(Affine Cipher)是一种古老的单字母替换密码,属于经典密码学范畴。 加密 $$ E(x) = (a\cdot x + b) \mod{m} $$ E(x)是加密后的字符的数值 x是明文字符的数值,通常是字母表的位置(A=0,B=1,…,Z=25) a和b是密钥,而且a必须和m互质(在字母表中,通常m=26) m是字符集的大小(对于英文字母,m=26) 加密步骤: 将明文字符转换为数字。 使用E(x)公式进行加密。 将加密后的数字转换回字符。 解密 仿射密码的解密过程可以用以下公式表示: $$ D(y) = a^-1\cdot(y-b)\mod{m} $$ D(y)是解密后的字符的数值 y是加密后的字符串的数值 $a^-1$是a的模逆元素,满足$a\cdot a^-1 \equiv 1\mod{m}$ b是加密时使用的密钥 m是字符集的大小 解密步骤: 计算a的模逆元素$a^-1$ 将加密字符转换为数字。 使用D(y)进行解密。 将解密后的数字转换回字符。 加密解密Py脚本(26个字母) #Affine Cipher (仿射密码) from gmpy2 import invert Htable="ABCDEFGHIJKLMNOPQRSTUVWXYZ" Ltable="abcdefghijklmnopqrstuvwxyz" #求最大公约数(GCD,Greatest Common Divisor) #辗转相除法 def gcd(a,b): #b=0时,整除了,即最大公约数 while b: a,b=b,a%b #b是余数,赋值给a,下一轮继续求余数 return a #判断a是否和b互质 def are_coprime(a,b): #最大公约数是1,则互质 return gcd(a,b)==1 def affine_encrypt(text,a,b,m): enc_text="" if are_coprime(a,m): for i in text: if 'A'<=i<='Z': enc_text+=Htable[(a*(Htable.index(i))+b)%m] elif 'a'<=i<='z': enc_text+=Ltable[(a*(Ltable.index(i))+b)%m] else: enc_text+=i return enc_text else: print("a和m不互质,无法加密") def affine_decrypt(text,a,b,m): dec_text="" if are_coprime(a,m): #好吧...其实扩展欧几里得和求模逆元还没学明白,就直接用了gmpy2的 a_inv = invert(a, m) print(a_inv) for i in text: if 'A'<=i<='Z': dec_text+=Htable[(a_inv * (Htable.index(i)-b) ) %m] elif 'a'<=i<='z': dec_text+=Ltable[(a_inv * (Ltable.index(i)-b) ) %m] else: dec_text+=i return dec_text else: print("a和m不互质,无法解密") c = affine_encrypt("flag{aff1n3_encrp4y}",3,4,26) print(f"密文:{c}") m = affine_decrypt(c,3,4,26) print(f"明文:{m}")

November 20, 2024 · 1 min · Yalois

🏁第十一届山东省大学生网络安全技能大赛WP

收获 拿了团体二等奖和个人二等奖,还不错 我们团队和团体一等奖就差一名,真是太可惜了。我pwn题签到没做出来,后悔… 一定抽空好好学学pwn 部分WriteUp misc 签到 直接提交给出的flag ezpic 附件:ezpic.png strings命令文件末尾有半段flag $ strings ezpic.png IHDR IDATx FDT$ &ffH iRDB$ ... ... ... ... a73b2de7499d614c} 拖入Stegsolve , 蓝色图层有二维码,扫描得到 flag{cf74bc8a2233179e flag{cf74bc8a2233179ea73b2de7499d614c} 简单编码 题目信息:60=?+? 附件信息 DJ?ELCaecBfBa?eeCAABBD?AfgBghDChab_N ROT47+ROT13 异常的流量 附件:异常的流量.pcap 观察流量包,一个dns查询一个响应,只要一个就行,用命令导出二进制数据 tshark -r 异常的流量.pcap -T fields -Y “ip.src==172.16.178.145” -e dns.qry.name > dnst1.txt 把dnst1.txt的多于的部分删除只留下0和1 观察发现,除去换行符,每行40个字符,共40行,方的,制作二维码 from PIL import Image from zlib import * MAX = 40 pic = Image.new("RGB",(MAX,MAX)) str = "这里放置除去换行符的0和1数据" i=0 for y in range(0,MAX): for x in range(0,MAX): if(str[i] == '1'): pic.putpixel([x,y],(0,0,0)) else:pic.putpixel([x,y],(255,255,255)) i = i+1 pic.show() pic.save("1.png") 生成1.png ...

October 28, 2024 · 3 min · Yalois

🪄从实例入门学习正则表达式

基础知识 正则表达式(Regular Expression,简称 regex 或 regexp)是一种用于描述字符串模式的工具,广泛应用于文本搜索、替换和数据验证等场景。 1. 基本字符 普通字符:匹配自身,如 a 匹配字母 “a”。 特殊字符:有特定意义的字符,如 .、*、?、+、^、$、[]、{}、()、\ 等。 2. 特殊字符的含义 .:匹配任意单个字符(除了换行符)。 *:匹配前一个字符零次或多次。 +:匹配前一个字符一次或多次。 ?:匹配前一个字符零次或一次。 ^:匹配字符串的开始。 $:匹配字符串的结束。 []:匹配方括号内的任意一个字符,例如 [abc] 匹配 “a”、“b” 或 “c”。 [^]:匹配不在方括号内的任意一个字符,例如 [^abc] 匹配除 “a”、“b”、“c” 以外的任意字符。 {n}:匹配前一个字符恰好 n 次。 {n,}:匹配前一个字符至少 n 次。 {n,m}:匹配前一个字符至少 n 次,但不超过 m 次。 3. 转义字符 \:用于转义特殊字符,使其失去特殊意义。例如,\. 匹配字面上的点号。 4. 分组与捕获 ():用于分组,可以将多个字符组合在一起进行匹配,并且可以捕获匹配的内容。 |:表示“或”操作,例如 a|b 匹配 “a” 或 “b”。 5. 预定义字符类 \d:匹配任何数字,等价于 [0-9]。 \D:匹配任何非数字字符。 \w:匹配任何字母、数字或下划线,等价于 [a-zA-Z0-9_]。 \W:匹配任何非字母数字字符。 \s:匹配任何空白字符(空格、制表符等)。 \S:匹配任何非空白字符。 6. 常用模式 邮箱地址:^[\w.-]+@[\w.-]+\.\w+$ 电话号码:^\d{3}-\d{3}-\d{4}$ URL:^(http|https)://[^\s/$.?#].[^\s]*$ 7. 贪婪与非贪婪匹配 贪婪匹配:尽可能多地匹配字符,例如 .*。 非贪婪匹配:尽可能少地匹配字符,使用 *?、+?、?? 等。 8. 边界匹配 \b:匹配单词边界。 \B:匹配非单词边界。 9. 标志 Flags i 表示忽略大小写 m 多行模式 s 允许 .匹配包括换⾏符在内的所有字符。 g global全局搜索,匹配⽂本中的所有实例。 10. 实践工具 常用的正则表达式工具和库包括: JavaScript: /pattern/ Python: re 模块 Java: java.util.regex 包 PHP: preg_* 函数 实例学习 1. 匹配邮政编码 邮政编码是非常重要的。例如,北京的邮政编码是100000,而上海的邮政编码是200000。广州的邮政编码为510000,深圳的邮政编码则是518000。此外,成都的邮政编码是610000,杭州的邮政编码为310000。 2. 匹配html标签 <!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>简单的网页</title> </head> <body> <h1>欢迎来到我的网页</h1> <p>这是一个简单的 HTML 示例。</p> <p>你可以访问 <a href="https://www.example.com">示例网站</a> 了解更多信息。</p> </body> </html> 3. 匹配小数 在最近的市场调查中,我们发现消费者的平均支出为256.75元,而在不同的产品类别中,电子产品的平均价格为899.99元,服装的平均价格为199.50元。与此同时,食品的平均支出为45.30元。调查还显示,消费者对新产品的满意度评分为4.5(满分5分),而对服务的满意度评分为3.8。 4. 匹配带有特定后缀的文件名 document1.docx presentation.pptx spreadsheet.xlsx image1.jpg photo.png audio.mp3 video.mp4 archive.zip script.py style.css report.pdf notes.txt database.sql backup.bak template.html config.json script.js image2.gif video.avi archive.tar.gz data.csv font.ttf markup.xml log.txt image3.bmp presentation.key project.rproj stylesheet.scss app.apk source.cpp main.go 在线匹配 <!DOCTYPE html> 正则表达式匹配训练 正则表达式匹配训练 匹配结果:

October 15, 2024 · 1 min · Yalois

🧊Google Lyra 封装成docker镜像

github仓库地址 https://github.com/Yalois/Google-Lyra-DockerImageBuild 可以在Release页面下载构建好的镜像导入。 详细过程看Dockerfile。 制作原因 CTF比赛中遇到过两次,一次是ISCC,然后就是最近的YLCTF。 记得ISCC那次我安装Lyra给我安装的我骂骂咧咧的想要把电脑砸了,主要是因为网络问题和依赖太多的问题,近期YLCTF又用到了,我又专门换回我的win系统里装好的wsl里的lyra解码的,安装确实有些麻烦。 为了提高使用效率,我决定将Lyra Linux环境封装成Docker镜像,并对lyra-1.3.2的WORKSPACE进行了修改,具体如下。 # 原来的 git_repository( name = "com_google_glog", remote = "https://github.com/google/glog.git", branch = "master" ) 因为可能仓库更新过导致代码不一致的问题会报以下错误 ERROR: /root/.cache/bazel/_bazel_root/d75f5abc8330122e59e1289f475094d7/external/com_google_glog/BUILD.bazel:7:13: no such package '@gflags//': The repository '@gflags' could not be resolved: Repository '@gflags' is not defined and referenced by '@com_google_glog//:glog' WARNING: /root/.cache/bazel/_bazel_root/d75f5abc8330122e59e1289f475094d7/external/com_google_audio_dsp/third_party/fft2d/BUILD:3:11: in linkstatic attribute of cc_library rule @com_google_audio_dsp//third_party/fft2d:fft2d: setting 'linkstatic=1' is recommended if there are no object files WARNING: errors encountered while analyzing target '//lyra/cli_example:encoder_main': it will not be built INFO: Analyzed target //lyra/cli_example:encoder_main (112 packages loaded, 3435 targets configured). INFO: Found 0 targets... ERROR: command succeeded, but not all targets were analyzed INFO: Elapsed time: 36.286s, Critical Path: 0.01s INFO: 1 process: 1 internal. FAILED: Build did NOT complete successfully 于是我修改为了和lyra同一时期的commit ...

October 14, 2024 · 1 min · Yalois