2019广东外语外贸大学CTF新手赛-密码学-RSA题解
题面
n=100000463700003241
e=17
密文:
分析:
题面已明示是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的素数表,通过二分搜索来实现爆破,速度更快
代码如下:
- #include <iostream>
- #include <map>
- #include <time.h>
- using namespace std;
- #define ll long long
- /**
- Miller_Rabin 算法进行素数测试
- 快速判断一个<2^63的数是不是素数,主要是根据费马小定理
- */
- //#define ll __int128
- const int S=; ///随机化算法判定次数
- ll MOD;
- ///计算ret=(a*b)%c a,b,c<2^63
- ll mult_mod(ll a,ll b,ll c)
- {
- a%=c;
- b%=c;
- ll ret=;
- ll temp=a;
- while(b)
- {
- if(b&)
- {
- ret+=temp;
- if(ret>c)
- ret-=c;//直接取模慢很多
- }
- temp<<=;
- if(temp>c)
- temp-=c;
- b>>=;
- }
- return ret;
- }
- ///计算ret=(a^n)%mod
- ll pow_mod(ll a,ll n,ll mod)
- {
- ll ret=;
- ll temp=a%mod;
- while(n)
- {
- if(n&)
- ret=mult_mod(ret,temp,mod);
- temp=mult_mod(temp,temp,mod);
- n>>=;
- }
- return ret;
- }
- ///通过费马小定理 a^(n-1)=1(mod n)来判断n是否为素数
- ///中间使用了二次判断,令n-1=x*2^t
- ///是合数返回true,不一定是合数返回false
- bool check(ll a,ll n,ll x,ll t)
- {
- ll ret=pow_mod(a,x,n);
- ll last=ret;//记录上一次的x
- for(int i=;i<=t;i++)
- {
- ret=mult_mod(ret,ret,n);
- if(ret==&&last!=&&last!=n-)
- return true;//二次判断为是合数
- last=ret;
- }
- if(ret!=)
- return true;//是合数,费马小定理
- return false;
- }
- ///Miller_Rabbin算法
- ///是素数返回true(可能是伪素数),否则返回false
- bool Miller_Rabbin(ll n)
- {
- if(n<) return false;
- if(n==) return true;
- if((n&)==) return false;//偶数
- ll x=n-;
- ll t=;
- while((x&)==)
- {
- x>>=;
- t++;
- }
- srand(time(NULL));
- for(int i=;i<S;i++)
- {
- ll a=rand()%(n-)+; // 生成随机数 0<a<=n-1 去试试
- if(check(a,n,x,t))
- return false;
- }
- return true;
- }
- int main(){
- ll n,p,q;
- cin>>n;
- for(int i=;i<;i++){
- if(Miller_Rabbin(i)){
- p=n/i;
- if(Miller_Rabbin(p)&&i*p==n){
- cout<<p<<" "<<i<<'\n';
- break;
- }
- }
- }
- }
爆破p q
爆破出p q 后我们手搓RSA加密来生成密钥
(拓展欧几里得算法、欧拉函数、快速幂运算)
代码如下:
- #include <iostream>
- using namespace std;
- #define ll long long
- ll exgcd(ll a,ll b,ll &x,ll &y){
- if(a==&&b==) return -;
- if(b==){
- x=,y=;
- return a;
- }
- ll d=exgcd(b,a%b,y,x);
- //cout<<a<<" "<<b<<'\n';
- y-=a/b*x;
- return d;
- }
- ll poww(ll a,ll b,ll c){ //快速幂取模
- ll ans(),base=a%c;
- //a=a%c;
- while(b){
- if(b&) ans=(ans*base)%c;
- base=base*base%c;
- b>>=;
- }
- return ans;
- }
- int main(){
- int flag();
- ll p,q,ou,ed,n,e(),x(),y(),num1,ans,s;
- cin>>flag;
- if(flag==){
- cout<<"依次输入 p q 与 e:";
- cin>>p>>q;
- n=p*q;
- ou=(p-)*(q-);
- cin>>e;
- num1=exgcd(e,ou,x,y);
- //y=y+e/ou*x;
- if(x<=)x=(x+ou)%ou;
- //x=(x+e)%e;
- cout<<"N值:"<<n<<'\n';
- cout<<"公钥:"<<e<<'\n';
- cout<<"密钥:"<<x<<'\n';
- return ;
- }
- if(flag==){
- cin>>s>>e>>n;
- ans=poww(s,e,n);
- cout<<ans<<'\n';
- }
- }
RSA加密生成密钥
得到密钥后我们手写py脚本,通过密文算出明文(快速幂运算)
- def poww(a,n,mod):
- ret=1
- tmp=a%mod
- while(n>0):
- if(n%2!=0):
- ret=(ret*tmp)%mod
- tmp=tmp*tmp%mod
- n>>=1
- return ret
- s1=e=n=1.0
- n=int(input())
- e=int(input())
- while(True):
- s1=int(input())
- ans=poww(s1,e,n)
- print(ans)
解密密文
观察生成的明文,我们发现其都在ASCII码的范围之内,尝试转出字符,可得到网址与博客密码
进入博客后可以看到一篇加密后的林肯的《底斯堡演讲》
因为题面提示,此密文为古典密码,我们可以通过分析字频(英文字母e i s)或者暴力破解(跑所有古典密码解密方案,并用词典进行对比),可以发现此加密为凯撒加密,即可得到flag
坑点、考点、思路总结:
首先你得会RSA加密(我学了一小时不到就来出题了)
在不会各种算法、数论知识的情况下可以借助外界工具解题,如在线因数分解,py库提供的种种数学调用
本题出题的目的是考察算法知识、数论知识、与对数据的分析判断,很多同学使用了各种外界工具来辅助解题,但依旧希望各位能够去了解、学习上述知识点与算法,为后续的密码学学习打下基础
2019广东外语外贸大学CTF新手赛-密码学-RSA题解的更多相关文章
- 2019年广东外语外贸大学程序设计竞赛(新手赛)-F题(好快的刀)题解
题面: 题目意为,任意连接两个圆的圆心形成一条直线,计算与该直线相交或相切的圆的数量,求这些直线最多能相交或相切多少个圆 解题思路: 遍历所有的圆,计算出两圆圆心生成的直线,再遍历其他的圆,检测这些圆 ...
- 2019字节跳动冬令营day7娱乐赛19题题解
啊没去听讲题,也没发纸质题解,电子版题解也没有 为最后几个unsolve自闭了一段时间才全都A掉 3个队友写的我没看的题通过人数蛮多就不管了 题目地址:https://pan.baidu.com/s/ ...
- 2019看雪CTF 晋级赛Q2第四题wp
上次参加2019看雪CTF 晋级赛Q2卡在了这道题上,虽然逆出算法,但是方程不会解,哈哈哈哈,果然数学知识很重要呀,现在记录一下. 首先根据关键信息,根据错误提示字符串定位到这里: 1 int __t ...
- PTA|团体程序设计天梯赛-练习题目题解锦集(C/C++)(持续更新中……)
PTA|团体程序设计天梯赛-练习题目题解锦集(持续更新中) 实现语言:C/C++: 欢迎各位看官交流讨论.指导题解错误:或者分享更快的方法!! 题目链接:https://pintia.cn/ ...
- 2019年湖南省大学生计算机程序设计竞赛 (HNCPC2019) 简要题解
2019年湖南省大学生计算机程序设计竞赛 (HNCPC2019) 简要题解 update10.01 突然发现叉姐把这场的题传到牛客上了,现在大家可以有地方提交了呢. 不知道该干什么所以就来水一篇题解 ...
- 南京邮电大学CTF密码学部分Writeup
异性相吸 1.xor 2.hex2binary 3.len(bin(miwen))==len(bin(mingwen)) # -*- coding:utf-8 -*- file_de = open(' ...
- 南京邮电大学CTF密码学之MD5-golang与php代码实现
题目内容:这里有一段丢失的md5密文 e9032???da???08????911513?0???a2 要求你还原出他并且加上nctf{}提交 已知线索 明文为: TASC?O3RJMV?WDJKX? ...
- python爬虫入门---第二篇:获取2019年中国大学排名
我们需要爬取的网站:最好大学网 我们需要爬取的内容即为该网页中的表格部分: 该部分的html关键代码为: 其中整个表的标签为<tbody>标签,每行的标签为<tr>标签,每行中 ...
- 哈尔滨工程大学ACM预热赛
https://ac.nowcoder.com/acm/contest/554#question A #include <bits/stdc++.h> using namespace st ...
随机推荐
- React 顶层 API
概览 组件 使用 React 组件可以将 UI 拆分为独立且复用的代码片段,每部分都可独立维护.你可以通过子类 React.Component 或 React.PureComponent 来定义 Re ...
- Common Substrings POJ - 3415 (后缀自动机)
Common Substrings \[ Time Limit: 5000 ms\quad Memory Limit: 65536 kB \] 题意 给出两个字符串,要求两个字符串公共子串长度不小于 ...
- HOL的多表查询——内连接、外连接
1.内连接: 由于学生和班级是多对一的关系,班级对应学生是一对多的关系,因此,需要先对学生和班级进行配置. (1)创建Student类(多的一方): package pers.zhb.domain; ...
- 洛谷P3834题解
若想要深入学习主席树,传送门. Description: 给定数列 \(\{a_n\}\) ,求闭区间 \([l,r]\) 的第 \(k\) 小的数. Method: 先对数据进行离散化,然后按照权值 ...
- 第08组 Alpha事后诸葛亮
组长博客 点这里! 总结思考 设想和目标 我们的软件要解决什么问题?是否定义得很清楚?是否对典型用户和典型场景有清晰的描述? 弥补Powerpoint中模板转换存在的缺陷,完善PPT模板一键转换的功能 ...
- load average 定义(网易面试)
1. load average 定义 linux系统中的Load对当前CPU工作量的度量.简单的说是进程队列的长度. Load Average 就是一段时间 (1 分钟.5分钟.15分钟) 内平均 L ...
- 如何保证MQ的顺序性?比如Kafka
三.如何保证消息的顺序性 1. rabbitmq 拆分多个queue,每个queue一个consumer,就是多一些queue而已,确实是麻烦点:或者就一个queue但是对应一个consumer,然后 ...
- 《Maven实战》整理
一.maven介绍 Maven是优秀的构建工具,能够帮我们自动化构建过程,从清理.编译.测试到生成报告,再到打包和部署. Maven能帮助我们标准化构建过程.在Maven之前,十个项目可能有十种构建方 ...
- vs开启,Windows 10磁盘占用100%解决办法
https://www.cnblogs.com/time-is-life/p/8888441.html 最后把Home Group相关的服务都改成禁用. 注意: 即使这两个服务没有启动也不行, 一定要 ...
- [转]理解Vuex的辅助函数mapState, mapActions, mapMutations用法
原文地址:https://www.cnblogs.com/tugenhua0707/p/9794423.html 在讲解这些属性之前,假如我们项目的目录的结构如下: ### 目录结构如下: demo1 ...