仿射密码-fanfie--affine
仿射密码
仿射密码 是一种专情密码,一对一替换 ~~
加密函数是
e(x) = ax + b (mod m)
其中a和m 互质,m是字母的数目。解码函数是
d(x) = a^-1(x - b) (mod m)
(打不出来凑合一下 a^-1 乘法逆元)
仿射例题
【攻防世界】 - - fanfie
先上题,该题来源于 BITSCTF 。 【题目链接】
下载附件,得到如下的字符串。 长度不长,大写字母和数字组成。 很容易让人想到 Base64/32 解密。
MZYVMIWLGBL7CIJOGJQVOA3IN5BLYC3NHI
先简单提一下 详细介绍可以看一下网上大佬的这篇 关于base系列的加密解密
- Base64 : 由
0-9、a-z、A-Z、+、/
及后缀 “=” 组成 将任意字节序列数据编码成ASCII字符串- Base32 : 用32个可打印字符
A-Z、2-7
对任意字节数据进行编码
然而通过Base64解码并没有发现什么。(这题脑洞是真的大!!怪不得叫“ fanfie”-幻想)
通过百度大佬 题解 才知:
[ ] 将
BITSCTF
进行Base32加密 附 Base32加密网站IJEVIU2DKRDA====
[ ] 得到的这串密文与题目给出的字符串进行比对
MZYVMIWLGBL7CIJOGJQVOA3IN5BLYC3NHI
IJEVIU2DKRDA====
发现上面相同的字母对应的下面的字母也一致。(如 M - I 、L - D)既然如此,那便有迹可循。
因为是Base32编码。那么对A-Z、2-7 进行编码:
A | B | C | D | E | F | G | H |
---|---|---|---|---|---|---|---|
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
I | J | K | L | M | N | O | P |
8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
Q | R | S | T | U | V | W | X |
16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 |
Y | Z | 2 | 3 | 4 | 5 | 6 | 7 |
24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 |
由此更直观可见,字母对应关系
3 ->11 4 ->24 8 ->12 20 ->8 21->21 25->9 26->22
这种一个字母替换一个字母的替换密码就是 仿射密码
加密函数是
e(x) = ax + b (mod m)
其中a和m 互质,m是字母的数目。解码函数是
d(x) = a^-1(x - b) (mod m)
(打不出来凑合一下 a^-1 乘法逆元)
如何进行仿射解密呢? 我们有俩种方法:
- 进行肉眼勘测和手动计算
- python脚本自动跑
先来看第一种: 由上述所有条件,我们可以自豪的断定: 仿射密码的 a = 13 b = 4
经过仿射解密 可得 :
MZYVMIWLGBL7CIJOGJQVOA3IN5BLYC3NHI --> IJEVIU2DKRDHWUZSKZ4VSMTUN5RDEWTNPU
第二种,上脚本:借鉴大佬 仿射加密解密脚本 欧几里得算法求解乘法逆元
已知 加密仿射的 a:13 b:4 模:32 第一步先求解 13关于模32的逆元
# 欧几里德算法求最大公约数
def get_gcd(a, b):
k = a // b
remainder = a % b
while remainder != 0:
a = b
b = remainder
k = a // b
remainder = a % b
return b
# 改进欧几里得算法求线性方程的x与y
def get_(a, b):
if b == 0:
return 1, 0
else:
k = a // b
remainder = a % b
x1, y1 = get_(b, remainder)
x, y = y1, x1 - k * y1
return x, y
a = input('a:')
b = input('b:')
a, b = int(a), int(b)
# 将初始b的绝对值进行保存
if b < 0:
m = abs(b)
else:
m = b
flag = get_gcd(a, b)
# 判断最大公约数是否为1,若不是则没有逆元
if flag == 1:
x, y = get_(a, b)
x0 = x % m # 对于Python '%'就是求模运算,因此不需要'+m'
print("所求的逆元:", x0) # x0就是所求的逆元
else:
print("Do not have!")
k1:仿射加密函数中的a
k2:仿射加密函数中的b
k3:13关于 模32 的逆元
输入到下面java代码中
import java.util.Scanner;
public class Main{
public static void main(String[] args) {
char[] form = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '2', '3', '4', '5', '6', '7'};
Scanner sc = new Scanner(System.in);
System.out.println("请输入待加密的明文:");
String MingWen = sc.nextLine();
MingWen=MingWen.toUpperCase();
final int K1 = 13; //仿射加密函数中的a
final int K2 = 4; //仿射加密函数中的b
final int K3 = 5; // 13关于 模32 的逆元
int [] cipherNum=new int[MingWen.length()];//用来存储数字化的密文
encryption(MingWen,form,K1,K2,K3,cipherNum);
}
public static void encryption(String MingWen,char[] form,int K1,int K2,int k3,int[] cipherNum){
char[] pla=new char[MingWen.length()];
for (int i = 0; i <MingWen.length() ; i++) {
pla[i]=MingWen.charAt(i);
}
int[] MingWenNumber=new int[pla.length];
for (int i = 0; i <pla.length ; i++) {
for (int j = 0; j <form.length ; j++) {
if (form[j]==pla[i]) {
MingWenNumber[i] = j;
}
}
}
//通过脚标将明文全部转化为数字
char[] cipher = new char[MingWen.length()];
char[] JieMI = new char[MingWen.length()];
int len = MingWen.length();//cipher密码数组 用来存储密文
for (int i = 0; i <MingWen.length() ; i++) {
int a= Math.floorMod((K1*MingWenNumber[i]+K2),32);
cipherNum[i]=a;
cipher[i]=form[a];
//计算密文并存入数组中
}
System.out.println("加密结果是:");
System.out.println(cipher);
for (int i =0;i<len;i++){
JieMI[i]=form[Math.floorMod(k3*(MingWenNumber[i]-K2),32)];
}
System.out.println("解密结果是:");
System.out.println(JieMI);
}
}
IJEVIU2DKRDHWUZSKZ4VSMTUN5RDEWTNPU
最后一步啦~ 对脚本跑出的代码进行 Base32 解码 。网站同上。
BITSCTF{S2VyY2tob2Zm}
再来一简单题!
【bugkuCtf】 -- affine
题目链接 请戳这里
u1s1,该题目就非常实诚。直接给出 a / b 以及 密文 并且 affine 直接明示 这是 仿射解密 。
- E(x) = (ax + b) (mod m) a=17 b = -8
szzyfimhyzd
话不多说,我们可以继续使用上面的脚本 也可以使用下面一种更快的脚本 搬自这位大佬
def get(a, b):
if b == 0:
return 1, 0
else:
k = a //b
remainder = a % b
x1, y1 = get(b, remainder)
x, y =y1, x1 - k * y1
return x, y
s = input("请输入解密字符:").upper()
a = int(input("请输入a:"))
b = int(input("请输入b:"))
#求a关于26的乘法逆元
x, y = get(a, 26)
a1 = x % 26
l= len(s)
for i in range(l):
cipher = a1 * (ord(s[i])- 65 - b) % 26
res=chr(cipher + 65)
print(res, end='')
因为题目已经明确给出 ,所以直接进行解析就好。
preflag = "szzyfimhyzd"
flags = []
for i in preflag:
flags.append(ord(i)-97)
flag = ""
for i in flags:
for j in range(0,26):
a = (17 * j - 8) % 26
if(a == i):
flag += chr(j+97)
print(flag)
那最后的flag就是:
affineshift
结语
最后:其实我蛮惊奇的。 fanfie && affine 取名上十分巧妙。
( 前一题是不是有暗示的意味在呢~~手动狗头 )
宝藏软件推荐
【强烈安利】 无意间知道了这个神仙软件 captfencoder (点击下载哦~)
里面聚合编码转换古典密码密码学其他编码实用工具!!
还是老规矩 :关于以上链接引用【侵权删】
若有错误之处,还请多多指正~~
【转载请放链接】 https://www.cnblogs.com/Jlay/p/crypto_fangshe.html
仿射密码-fanfie--affine的更多相关文章
- nyoj 仿射密码
仿射密码 时间限制:1000 ms | 内存限制:65535 KB 难度:1 描述 仿射密码是替换密码的另一个特例,可以看做是移位密码和乘数密码的结合.其加密变换如下: E(m)=(k1*m+k2) ...
- NYOJ-770仿射密码,乘数密码与移位密码的结合;
仿射密码 时间限制:1000 ms | 内存限制:65535 KB 难度:1 -> Link <- 和乘数密码差不多: 加密算法:Ek(m)=(k1*m+k2)%q;gcd(k ...
- 仿射密码Python实现
算法分析 仿射密码结合了移位密码和乘数密码的特点,是移位密码和乘数密码的组合. 仿射密码的加密算法就是一个线性变化,即对明文字符x,对应的密文字符为y=ax+b(mod26)其中,a, b属于Z26且 ...
- 使用Python解密仿射密码
新学期有一门密码学课,课上老师布置了一道密码学题,题目如下: 解密由仿射密码加密的密文“DBUHU SPANO SMPUS STMIU SBAKN OSMPU SS” 想解密这个密文,首先必须要知道仿 ...
- NYOJ题目770仿射密码
aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAs4AAAIUCAIAAACFKz0yAAAgAElEQVR4nO3dPXLruLaG4TsJ5RqIYw
- CTF中常见密码题解密网站总结
0x00.综合 网站中包含大多编码的解码. http://web2hack.org/xssee/ https://www.sojson.com/ http://web.chacuo.net/ 0x01 ...
- Bugku-CTF加密篇之affine(y = 17x-8 flag{szzyfimhyzd})
affine y = 17x-8 flag{szzyfimhyzd} 答案格式:flag{*} 来源:第七届山东省大学生网络安全技能大赛
- OpenGL 模型视图投影矩阵 仿射矩阵
矩阵基础知识 要对矩阵进行运算,必须先要了解矩阵的计算公式,这个知识的内容涉及到了线性代数. 我们知道在Cocos2dx中,有关于平移,旋转,缩放等等操作,都必须要进行矩阵的乘法. 只需要一张图就能理 ...
- ctf古典密码从0到
本文首发于“合天智汇”公众号 作者:淡灬看夏丶恋雨 古典密码和现代密码的区别: 代换密码 单表代换密码 字符或数学型 凯撒密码 仿射密码 四方密码 培根密码 图表 标准银河字母 圣堂武士密码 猪圈密码 ...
随机推荐
- Scrapy中get和extract_first的区别
在scrapy中,从xpath中取得selector对象后,需要取出需要的数据. 使用get以及getall获取的是带标签的数据 比如 <p>这是一段文字</p> 如果用get ...
- js逻辑程序
JavaScript 是 Web 的编程语言. 所有现代的 HTML 页面都使用 JavaScript. JavaScript 非常容易学. 本教程将教你学习从初级到高级 JavaScript 知识. ...
- python的多线程和java的多线程之间的区别
在python中,由于Cpython解释器的全局解释器的存在,那么多线程的话在同一时刻只能有一个线程执行,意思就是python中的多线程只能并发执行, 没有办法实现真正的并行,也就是无法利用多核CPU ...
- Java实现评论回复功能
目录 一.分类方式 1.单一型 2.嵌套型 3.两层型 二.实现原理 1.单一型 2.嵌套型 3.两层型 使用递归循环开发评论回复功能,适用于大部分的简单单体应用 评论功能或许是大多数的单体应用之中会 ...
- DES 实现
原理 加密 置换: IP逆置换: 迭代: PC-1置换: PC-2置换: 子秘钥的生成: 加密函数f: 解密 代码 // C语言实现 #include<stdio.h> #include& ...
- Java才是世界上最好的语言,Java在高频交易中替代C++
高频交易 高频交易是指从那些人们无法利用的极为短暂的市场变化中寻求获利的计算机化交易,比如,某种证券买入价和卖出价差价的微小变化,或者某只股票在不同交易所之间的微小价差.在高频交易中,自动化应用程序每 ...
- ros启动节点Error: package 'chapter2_tutorials' not found问题
在学习ROS时,实现节点之间的通信时,参考ROS机器人高效编程,每次启动节点的时候 $ rosrun chapter2_tutorials example1_a 都会提示 Error: package ...
- 服务网格istio概念应知应会
一.背景 最近架构组基于istio开发了服务网格(Service Mesh)平台,借此机会把相关的背景知识做一次学习和记录,方便回头查看. 初版的效果: 二.istio 官方手册:https://is ...
- Reactor详解之:异常处理
目录 简介 Reactor的异常一般处理方法 各种异常处理方式详解 Static Fallback Value Fallback Method Dynamic Fallback Value Catch ...
- Dem地形数据转换为cass支持的dat格式教程
一.获取dem数据各类精度的dem高程数据下载这里不赘述,可以查阅这篇文章:高程数据下载 这里我们以12.5m精度的dem为例进行转换: 二.将dem数据转换为文本我们这里先将地形数据加载入globa ...