题面

n=100000463700003241

e=17

密文:

  1.  

分析:

题面已明示是RSA加密,已公开n与公钥e,n为1e18内的数字(64位).要爆破RSA,显然是先分析n的值。

n的值是由两个素数p和q相乘得出,所以我们需要将n因数分解。

n为64位,可能有1e18内的任意一对素数生成,计算机每秒运行少于1e9次,所以n^2暴力的素数表爆破是时间过长的。我们需要优化爆破算法。

我们可以取一个素数p,q=n/p,检测q是否为素数,q*p是否为n,以此来爆破p q(耗时1200秒左右)

根据这个思路,我们用米勒素数判定来检测p q即可实现(素数打表速度过慢)

也可以通过生成1e9的素数表,通过二分搜索来实现爆破,速度更快

代码如下:

  1. #include <iostream>
  2. #include <map>
  3. #include <time.h>
  4. using namespace std;
  5. #define ll long long
  6. /**
  7. Miller_Rabin 算法进行素数测试
  8. 快速判断一个<2^63的数是不是素数,主要是根据费马小定理
  9. */
  10. //#define ll __int128
  11. const int S=; ///随机化算法判定次数
  12. ll MOD;
  13. ///计算ret=(a*b)%c a,b,c<2^63
  14. ll mult_mod(ll a,ll b,ll c)
  15. {
  16. a%=c;
  17. b%=c;
  18. ll ret=;
  19. ll temp=a;
  20. while(b)
  21. {
  22. if(b&)
  23. {
  24. ret+=temp;
  25. if(ret>c)
  26. ret-=c;//直接取模慢很多
  27. }
  28. temp<<=;
  29. if(temp>c)
  30. temp-=c;
  31. b>>=;
  32. }
  33. return ret;
  34. }
  35.  
  36. ///计算ret=(a^n)%mod
  37. ll pow_mod(ll a,ll n,ll mod)
  38. {
  39. ll ret=;
  40. ll temp=a%mod;
  41. while(n)
  42. {
  43. if(n&)
  44. ret=mult_mod(ret,temp,mod);
  45. temp=mult_mod(temp,temp,mod);
  46. n>>=;
  47. }
  48. return ret;
  49. }
  50.  
  51. ///通过费马小定理 a^(n-1)=1(mod n)来判断n是否为素数
  52. ///中间使用了二次判断,令n-1=x*2^t
  53. ///是合数返回true,不一定是合数返回false
  54. bool check(ll a,ll n,ll x,ll t)
  55. {
  56. ll ret=pow_mod(a,x,n);
  57. ll last=ret;//记录上一次的x
  58. for(int i=;i<=t;i++)
  59. {
  60. ret=mult_mod(ret,ret,n);
  61. if(ret==&&last!=&&last!=n-)
  62. return true;//二次判断为是合数
  63. last=ret;
  64. }
  65. if(ret!=)
  66. return true;//是合数,费马小定理
  67. return false;
  68. }
  69.  
  70. ///Miller_Rabbin算法
  71. ///是素数返回true(可能是伪素数),否则返回false
  72. bool Miller_Rabbin(ll n)
  73. {
  74. if(n<) return false;
  75. if(n==) return true;
  76. if((n&)==) return false;//偶数
  77. ll x=n-;
  78. ll t=;
  79. while((x&)==)
  80. {
  81. x>>=;
  82. t++;
  83. }
  84. srand(time(NULL));
  85. for(int i=;i<S;i++)
  86. {
  87. ll a=rand()%(n-)+; // 生成随机数 0<a<=n-1 去试试
  88. if(check(a,n,x,t))
  89. return false;
  90. }
  91. return true;
  92. }
  93. int main(){
  94. ll n,p,q;
  95. cin>>n;
  96. for(int i=;i<;i++){
  97. if(Miller_Rabbin(i)){
  98. p=n/i;
  99. if(Miller_Rabbin(p)&&i*p==n){
  100. cout<<p<<" "<<i<<'\n';
  101. break;
  102. }
  103. }
  104. }
  105. }

爆破p q

爆破出p q 后我们手搓RSA加密来生成密钥

(拓展欧几里得算法、欧拉函数、快速幂运算)

代码如下:

  1. #include <iostream>
  2. using namespace std;
  3. #define ll long long
  4. ll exgcd(ll a,ll b,ll &x,ll &y){
  5.  
  6. if(a==&&b==) return -;
  7. if(b==){
  8. x=,y=;
  9. return a;
  10. }
  11. ll d=exgcd(b,a%b,y,x);
  12. //cout<<a<<" "<<b<<'\n';
  13. y-=a/b*x;
  14. return d;
  15. }
  16. ll poww(ll a,ll b,ll c){ //快速幂取模
  17. ll ans(),base=a%c;
  18. //a=a%c;
  19. while(b){
  20. if(b&) ans=(ans*base)%c;
  21. base=base*base%c;
  22. b>>=;
  23. }
  24. return ans;
  25. }
  26.  
  27. int main(){
  28. int flag();
  29. ll p,q,ou,ed,n,e(),x(),y(),num1,ans,s;
  30. cin>>flag;
  31. if(flag==){
  32. cout<<"依次输入 p q 与 e:";
  33. cin>>p>>q;
  34. n=p*q;
  35. ou=(p-)*(q-);
  36. cin>>e;
  37. num1=exgcd(e,ou,x,y);
  38. //y=y+e/ou*x;
  39. if(x<=)x=(x+ou)%ou;
  40. //x=(x+e)%e;
  41. cout<<"N值:"<<n<<'\n';
  42. cout<<"公钥:"<<e<<'\n';
  43. cout<<"密钥:"<<x<<'\n';
  44. return ;
  45. }
  46. if(flag==){
  47. cin>>s>>e>>n;
  48. ans=poww(s,e,n);
  49. cout<<ans<<'\n';
  50. }
  51. }

RSA加密生成密钥

得到密钥后我们手写py脚本,通过密文算出明文(快速幂运算)

  1. def poww(a,n,mod):
  2. ret=1
  3. tmp=a%mod
  4. while(n>0):
  5. if(n%2!=0):
  6. ret=(ret*tmp)%mod
  7. tmp=tmp*tmp%mod
  8. n>>=1
  9. return ret
  10. s1=e=n=1.0
  11. n=int(input())
  12. e=int(input())
  13. while(True):
  14. s1=int(input())
  15. ans=poww(s1,e,n)
  16. print(ans)

解密密文

观察生成的明文,我们发现其都在ASCII码的范围之内,尝试转出字符,可得到网址与博客密码

进入博客后可以看到一篇加密后的林肯的《底斯堡演讲》

因为题面提示,此密文为古典密码,我们可以通过分析字频(英文字母e i s)或者暴力破解(跑所有古典密码解密方案,并用词典进行对比),可以发现此加密为凯撒加密,即可得到flag

坑点、考点、思路总结:

首先你得会RSA加密(我学了一小时不到就来出题了)

在不会各种算法、数论知识的情况下可以借助外界工具解题,如在线因数分解,py库提供的种种数学调用

本题出题的目的是考察算法知识、数论知识、与对数据的分析判断,很多同学使用了各种外界工具来辅助解题,但依旧希望各位能够去了解、学习上述知识点与算法,为后续的密码学学习打下基础

2019广东外语外贸大学CTF新手赛-密码学-RSA题解的更多相关文章

  1. 2019年广东外语外贸大学程序设计竞赛(新手赛)-F题(好快的刀)题解

    题面: 题目意为,任意连接两个圆的圆心形成一条直线,计算与该直线相交或相切的圆的数量,求这些直线最多能相交或相切多少个圆 解题思路: 遍历所有的圆,计算出两圆圆心生成的直线,再遍历其他的圆,检测这些圆 ...

  2. 2019字节跳动冬令营day7娱乐赛19题题解

    啊没去听讲题,也没发纸质题解,电子版题解也没有 为最后几个unsolve自闭了一段时间才全都A掉 3个队友写的我没看的题通过人数蛮多就不管了 题目地址:https://pan.baidu.com/s/ ...

  3. 2019看雪CTF 晋级赛Q2第四题wp

    上次参加2019看雪CTF 晋级赛Q2卡在了这道题上,虽然逆出算法,但是方程不会解,哈哈哈哈,果然数学知识很重要呀,现在记录一下. 首先根据关键信息,根据错误提示字符串定位到这里: 1 int __t ...

  4. PTA|团体程序设计天梯赛-练习题目题解锦集(C/C++)(持续更新中……)

    PTA|团体程序设计天梯赛-练习题目题解锦集(持续更新中) 实现语言:C/C++:      欢迎各位看官交流讨论.指导题解错误:或者分享更快的方法!! 题目链接:https://pintia.cn/ ...

  5. 2019年湖南省大学生计算机程序设计竞赛 (HNCPC2019) 简要题解

    2019年湖南省大学生计算机程序设计竞赛 (HNCPC2019) 简要题解 update10.01 突然发现叉姐把这场的题传到牛客上了,现在大家可以有地方提交了呢. 不知道该干什么所以就来水一篇题解 ...

  6. 南京邮电大学CTF密码学部分Writeup

    异性相吸 1.xor 2.hex2binary 3.len(bin(miwen))==len(bin(mingwen)) # -*- coding:utf-8 -*- file_de = open(' ...

  7. 南京邮电大学CTF密码学之MD5-golang与php代码实现

    题目内容:这里有一段丢失的md5密文 e9032???da???08????911513?0???a2 要求你还原出他并且加上nctf{}提交 已知线索 明文为: TASC?O3RJMV?WDJKX? ...

  8. python爬虫入门---第二篇:获取2019年中国大学排名

    我们需要爬取的网站:最好大学网 我们需要爬取的内容即为该网页中的表格部分: 该部分的html关键代码为: 其中整个表的标签为<tbody>标签,每行的标签为<tr>标签,每行中 ...

  9. 哈尔滨工程大学ACM预热赛

    https://ac.nowcoder.com/acm/contest/554#question A #include <bits/stdc++.h> using namespace st ...

随机推荐

  1. React 顶层 API

    概览 组件 使用 React 组件可以将 UI 拆分为独立且复用的代码片段,每部分都可独立维护.你可以通过子类 React.Component 或 React.PureComponent 来定义 Re ...

  2. Common Substrings POJ - 3415 (后缀自动机)

    Common Substrings \[ Time Limit: 5000 ms\quad Memory Limit: 65536 kB \] 题意 给出两个字符串,要求两个字符串公共子串长度不小于 ...

  3. HOL的多表查询——内连接、外连接

    1.内连接: 由于学生和班级是多对一的关系,班级对应学生是一对多的关系,因此,需要先对学生和班级进行配置. (1)创建Student类(多的一方): package pers.zhb.domain; ...

  4. 洛谷P3834题解

    若想要深入学习主席树,传送门. Description: 给定数列 \(\{a_n\}\) ,求闭区间 \([l,r]\) 的第 \(k\) 小的数. Method: 先对数据进行离散化,然后按照权值 ...

  5. 第08组 Alpha事后诸葛亮

    组长博客 点这里! 总结思考 设想和目标 我们的软件要解决什么问题?是否定义得很清楚?是否对典型用户和典型场景有清晰的描述? 弥补Powerpoint中模板转换存在的缺陷,完善PPT模板一键转换的功能 ...

  6. load average 定义(网易面试)

    1. load average 定义 linux系统中的Load对当前CPU工作量的度量.简单的说是进程队列的长度. Load Average 就是一段时间 (1 分钟.5分钟.15分钟) 内平均 L ...

  7. 如何保证MQ的顺序性?比如Kafka

    三.如何保证消息的顺序性 1. rabbitmq 拆分多个queue,每个queue一个consumer,就是多一些queue而已,确实是麻烦点:或者就一个queue但是对应一个consumer,然后 ...

  8. 《Maven实战》整理

    一.maven介绍 Maven是优秀的构建工具,能够帮我们自动化构建过程,从清理.编译.测试到生成报告,再到打包和部署. Maven能帮助我们标准化构建过程.在Maven之前,十个项目可能有十种构建方 ...

  9. vs开启,Windows 10磁盘占用100%解决办法

    https://www.cnblogs.com/time-is-life/p/8888441.html 最后把Home Group相关的服务都改成禁用. 注意: 即使这两个服务没有启动也不行, 一定要 ...

  10. [转]理解Vuex的辅助函数mapState, mapActions, mapMutations用法

    原文地址:https://www.cnblogs.com/tugenhua0707/p/9794423.html 在讲解这些属性之前,假如我们项目的目录的结构如下: ### 目录结构如下: demo1 ...