攻略

  • 实验描述
  • 实验分析
  • 编程实现
    • py3 实现
    • c++ 实现

实验描述

  1. 问题描述

    仿射密码系统用五元组(P,C,K,E,D)表示,设 P = C = { 计算机学院网络工程信息安全,我们热爱中华人民共和国。大家 } 。

    现在截获了一段密文 “和院程安我爱计” 。

    请编程分析出明文。

  2. 基本要求

    程序要求界面友好,自动分析程度高,能输出加密所用的密钥和明文。

  3. 实现提示

    申请三个字符数组 Z,C,M 。

    Z = { 计算机学院网络工程信息安全,我们热爱中华人民共和国。大家 } ,

    C = “和院程安我爱计”,

    M 保存分析所得的明文。

    密文是通过
    ek(m)=(am+b)mod28e_k(m)=(am+b )\mod 28 ek​(m)=(am+b)mod28
    得到的,为了解密我们使用
    dk(c)=a−1(c−b)mod28d_k(c)=a^{-1}(c-b)\mod 28 dk​(c)=a−1(c−b)mod28
    这里有一个函数要先实现:

    int gcd(int n, int m) {int r, temp;if (n < m) {temp = n;n = m;m = temp;}while (m != 0) {r = n % m;n = m;m = r;}return n;
    }
    

    有了以上的准备工作,我们就可以编写程序的主要部分了,它是一个多重循环:

    for (a = 2; a < 28; a++)if (gcd(a, 28) == 1) {/*求a的乘法逆元p */for (b = 2; b < 28; b++)if ((a * b) % 28 == 1) {p = b;break;}/* 用dk(c)=p(c-b) mod 28 */for (b = 0; b < 28; b++) {//对数组C进行处理,输出k=(a,b)和M,M有意义程序结束,分析完成。}} else continue;
    

实验分析

我们先来看一般仿射密码的五元组:
M=C=Z26M=C=Z_{26} M=C=Z26​

K={(a,b)∣(a,26)=1且1≤a≤25,0≤b≤25}K=\{(a,b)|(a,26)=1 且 1\le a \le 25,0\le b \le 25\} K={(a,b)∣(a,26)=1且1≤a≤25,0≤b≤25}

C=(am+b)mod26C=(am+b)\mod 26 C=(am+b)mod26

M=a−1(c−b)mod26M=a^{-1}(c-b)\mod 26 M=a−1(c−b)mod26

一般我们的仿射密码是单字母表密码,所以明文空间和密文空间都是 26 字母,但是这题我们已经给定了 Z 和 C ,所以替换表应该改成下面的形式:

所以加解密公式也应如实验描述中的那样,变为以下形式:
C=(am+b)mod28C=(am+b)\mod 28 C=(am+b)mod28

M=a−1(c−b)mod28M=a^{-1}(c-b)\mod 28 M=a−1(c−b)mod28

再来看编程方面。

我们知道,如果要求一个数 a n 的模逆,必须 an 要互素,这题的基本思路就是通过爆破 ab 解密找到意思通顺的明文,所以在求 a 的模逆时,我们先用 gcd(a, 28) == 1 判断了其是否可逆。

爆破了 a 后就是求其逆元,逆元这里也是通过爆破,因为 28 很小,如果是求大数逆元,我们需要用到扩展欧几里得或者欧拉定理来求解,最后就是爆破 b 求解明文。

综上,我们的最终思路为:

  1. 找出 C 在 Z 中每个字对应的位置,并将所有位置存储在一个列表(py)/ 数组(c/c++)中。
  2. 爆破 a,求出可逆 a 的逆元 p
  3. 爆破 b,运用公式 dk(c)=p(c-b) mod 28 ,输出对应密钥 (a,b) 和解密结果。

编程实现

py3 实现

人生苦短,我用 python 。

# Created by snovving on 2021/3/7.
Z = "计算机学院网络工程信息安全,我们热爱中华人民共和国。大家"
C = "和院程安我爱计"
pos = []def gcd(n, m):if n < m:temp = nn = mm = tempwhile m != 0:r = n % mn = mm = rreturn nif __name__ == '__main__':# 查找 C 的每个字符在 Z 中的位置,并存到 pos 列表中for i in C:pos.append(Z.find(i))# 爆破 afor a in range(2, 28):# 判断 a 是否可逆if gcd(a, 28) == 1:# 求 a 的逆元for b in range(2, 28):if (a * b) % 28 == 1:p = bbreak# 爆破 bfor b in range(0, 28):# 注意清空每一次的解密结果res = ""for i in pos:i = p * (i - b) % 28res += Z[i]print(f"当 a={a},b={b} 时,解密结果为:{res}")

可以验证一下( “我” 是 14,“和” 是 23):
C=(3∗14+9)mod28=23C=(3*14+9)\mod28=23 C=(3∗14+9)mod28=23

c++ 实现

我在用 c++ 实现的时候遇到了很多问题,逐渐开始无法理解这一切了.jpg——详见 这篇博客 来区分 size()sizeof()strlen()str.length() 这四个函数,看完后我们再来分析。

c++ 中的 str.length()str.size() 都返回的字节数,而我们题目中的 Z 和 C 都是汉字,GBK 编码中占两个字节( UTF-8 中是三个字节),想简单地通过 str.find_first_of(str1) 找到位置是不行的,看下面的示例:

#include <iostream>
#include <string>using namespace std;int main() {string Z1 = "计算机学院网络工程信息安全,我们热爱中华人民共和国。大家";string C1 = "和院程安我爱计";
//    string Z1="abcdefg";
//    string C1="gb";cout << C1.length() << endl;cout << C1[0] << endl;cout << Z1.find_first_of(C1[0]) << endl;
}

汉字的 Z1 和 C1,可以看到 C1[0] 并不能显示出来,且长度是两倍:


以下为对上述结果的一些猜想。

对于这个结果,我想了很多,为什么第一个位置是 9 呢?这牵扯到 c++ 是如何处理中文的问题,在搜寻官方文档无果后,我突然想起了课本中的区位码:

关于区位码的介绍我觉得 这篇文章 很好。

将汉字转为区位码

计 2838
算 4367
机 2790
学 4907
院 5226
网 4588
络 3471
工 2504
程 1944
信 4837
息 4702
安 1618
全 4011
, 0312
我 4650
们 3539
热 4040
爱 1614
中 5448
华 2710
人 4043
民 3581
共 2518
和 2645
国 2590
。 0103
大 2083
家 2850

这是我暂时找到的最合理的解释了:

比如例子中的 C1[0] 是 “和” 的第一个字节,区位码 2645,分成两部分 26 和 45 。

我们再来看对应 Z 第 9 个是 “院” 的 5226 中的 26 (从 0 开始计数),所以才有 Z1.find_first_of(C1[0]) 为 9 ,不知道这个想法对不对,如果有更加官方的解释请在评论区提醒我,我会及时进行验证并修改文章,谢谢!


英文的 Z1 和 C1,英文只占一个字节,所以能显示:

综上,所以才有下面代码中的匹配两个字节来得出位置:

// Created by snovving on 2021/3/7.
#include <iostream>
#include <string>using namespace std;int gcd(int n, int m) {int r, temp;if (n < m) {temp = n;n = m;m = temp;}while (m != 0) {r = n % m;n = m;m = r;}return n;
}int main() {string Z = "计算机学院网络工程信息安全,我们热爱中华人民共和国。大家";string C = "和院程安我爱计";string res;int clen = C.length() / 2;int zlen = Z.length() / 2;int p, a, b, c, pos[clen];// 查找 C 在 Z 中的位置for (int i = 0; i < clen; i++) {for (int j = 0; j < zlen; j++) {if (Z[2 * j] == C[2 * i] && Z[2 * j + 1] == C[2 * i + 1]) {pos[i] = j;}}}// 爆破 afor (a = 2; a < 28; a++) {// 判断 a 是否可逆if (gcd(a, 28) == 1) {// 求出 a 的逆元 pfor (p = 2; p < 28; p++) {if ((a * p) % 28 == 1) break;}// 爆破 bfor (b = 0; b < 28; b++) {// 清空每一次的结果res.clear();// 解密for (int i = 0; i < clen; i++) {// 特别注意小于 0 的情况,这与 py 不同,因为我们需要加上两字节c = (p * (pos[i] - b)) % 28;if (c >= 0) {res = res + Z[2 * c] + Z[2 * c + 1];} else {c = c + 28;res = res + Z[2 * c] + Z[2 * c + 1];}}cout << "当 a=" << a << ",b=" << b << " 时,解密结果为:" << res << endl;}}}
}

密码学课设-仿射密码的攻击相关推荐

  1. 合肥工业大学密码学课设-RSA

    ✅作者简介:CSDN内容合伙人.信息安全专业在校大学生

  2. 密码学基础--仿射密码

     在仿射密码中,加密函数定义为: e(x)=(ax+b)mod26 a,bZ.因为这样的函数被称为仿射函数,所以这样的密码体制也称为仿射密码(可以看出,当a=1时,其对应的正是移位密码). 为了能对密 ...

  3. 密码学—仿射密码实验报告

    古典密码算法实验报告 姓名:空の城 学号:你猜 专业班级:网络安全专业 一.实验目的 通过编程实现替代密码算法--仿射密码算法,加深对古典密码体制的了解,为深入学习密码学奠定基础. 二.实验原理 仿射 ...

  4. 【密码学原理与实践】(三)仿射密码 符java代码实现

    仿射密码(Affine Cipher) 转载请著明出处 仿射密码是代换密码的一种特殊情况. 在学习仿射密码之前我们首先需要了解几个定理 定理 同余方程唯一解定理 设a ∈ Zm,对任意的b∈Zm,同余 ...

  5. 仿射密码 [GKCTF2020]小学生的密码学

    在仿射密码中,加密函数定义为: e(x)=(ax+b)mod26 a,b\inZ_{26}.因为这样的函数被称为仿射函数,所以这样的密码体制也称为仿射密码 符合仿射密码的特征 在线解密 然后将 sor ...

  6. 【现代密码学】仿射密码加密

    //仿射变换主要是乘法与加法变换的结合 //C=a*m+k mod 26 加密 //M=a^-1(c-k)mod 26 解密 #include <iostream> #include< ...

  7. 密码学基础(二)单表---置换密码 凯撒密码 棋盘密码 乘法密码 仿射密码 多表---vigenere方阵

    1古典密码 (1)置换密码 明文字母重新排列,字母本身不变,但是位置发生变化(倒序或者按照按照数组排列后以行或列重新组合) (2)代替密码 分为单表代替密码和多表代替密码 单表代替密码中代表性的 凯撒 ...

  8. 计算机网路络课设_学生宿舍网络规划与设计

    xxx大学学生宿舍网络规划与设计 摘 要 目 录 1 前 言 2 案例描述 3 项目分析 3.1 需求分析 3.1.1 网络主干线需求分析 3.1.2 网络系统的设计原则 3.2 可行性分析 3.2. ...

  9. python用表达式解密密文_基于Python解密仿射密码

    新学期有一门密码学课,课上老师布置了一道密码学题,题目如下: 解密由仿射密码加密的密文"DBUHU SPANO SMPUS STMIU SBAKN OSMPU SS" 想解密这个密 ...

最新文章

  1. bootstrap设置button不显示_电脑便签怎么显示不关闭?电脑云便签敬业签怎么设置显示桌面?...
  2. java join 源码_join on 和where 一起使用的细节
  3. java中 set集合_第8篇 Java中的集合(Set)
  4. 卡诺模型案例分析_3个维度看竞品分析!
  5. grafana官方使用文档_5. Centos7 下部署使用 nmon2influxdb
  6. java 启动jar包JVM参数
  7. android+4.0访问网络,Android 中从4.0以后无法在主线程访问网络的解决办法。
  8. Eclipse创建带JavaBean的JSP程序
  9. 通过温度和湿度计算露点函数
  10. matlab卡住了怎么办,如何解决matlab运行慢或死机的情况
  11. 百度地图地图API(常用)
  12. 如何用PR制作GIF图(Premiere)
  13. 机器学习PAI为你自动写歌词,妈妈再也不用担心我的freestyle了(提供数据、代码)...
  14. java阶梯计费,机器智能审核阶梯计费方式
  15. 《少年维特之烦恼》经典语录:残冬行将消失,春天恍若来临。
  16. 梦想世界3手游服务器维护,梦想世界手游进不去 闪退及登录不上解决方法
  17. u深度做linux启动盘,u深度u盘启动盘制作教程
  18. OpenCvSharp人脸检测(一) HaarCascade与LbpCascade人脸检测
  19. IT男人必学的20大泡妞妙招(请允许我蛋疼的转一下)
  20. 简易垂直搜索引擎的核心算法总结

热门文章

  1. 【详解】计算机视觉之目标分割
  2. 【转】爆笑程序员的笑话集锦
  3. 考研预报名显示服务器错误,2021考研预报名常见问题:考研预报名入口无法打开怎么办?...
  4. 2004年人民大学新闻研究生参考书目(四)
  5. 重温大师经典:Martin Fowler的持续集成
  6. Phalcon使用多语言环境(切换中文/英文等)
  7. js迷宫自动走html,JavaScript简单实现迷宫问题求解
  8. 技术,记载钓鱼网站的多次渗
  9. PYTHON+UDP+双向通信
  10. 最新和平精英画质助手iApp安卓源码+全开源/可用