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 ...
随机推荐
- 轻松学习之三——IMP指针的作用
http://www.jianshu.com/p/425a39d43d16 可能大家一直看到有许多朋友在Runtime相关文章中介绍IMP指针的概念,那么IMP究竟有什么实际作用呢?让我们先从一个函数 ...
- combineReducers(reducers)
combineReducers(reducers) 随着应用变得越来越复杂,可以考虑将 reducer 函数 拆分成多个单独的函数,拆分后的每个函数负责独立管理 state 的一部分. combine ...
- POJ2139-Six Degrees of Cowvin Bacon-(Floyd_Warshall)
题意:有n只牛拍电影m部电影,知道每部电影有哪些牛参与,一起拍电影的牛之间维度为1,ab拍电影则ab之间的维度为1,如果bc一起拍电影,ac没有一起,则ac之间的维度为2,以此类推.求哪知牛到所有牛之 ...
- C# 按行读取文件 从某行开始取
; FileStream fs = new FileStream(e.FullPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); u ...
- 20101010 exam
目录 2018 10.10 exam 解题报告 T1:LOJ #10078 新年好 题目描述(原题来自:CQOI 2005): 输入格式: 输出格式: 样例输入: 样例输出: 数据范围与提示: 思路: ...
- 洛谷 P1972 [SDOI2009]HH的项链-二维偏序+树状数组+读入挂(离线处理,思维,直接1~n一边插入一边查询),hahahahahahaha~
P1972 [SDOI2009]HH的项链 题目背景 无 题目描述 HH 有一串由各种漂亮的贝壳组成的项链.HH 相信不同的贝壳会带来好运,所以每次散步完后,他都会随意取出一段贝壳,思考它们所表达的含 ...
- Gradle系列教程之依赖管理
这一章我将介绍Gradle对依赖管理的强大支持,学习依赖分组和定位不同类型仓库.依赖管理看起来很容易,但是当出现依赖解析冲突时就会很棘手,复杂的依赖关系可能导致构建中依赖一个库的多个版本.Gradle ...
- eclipse修改代码没用、debug无法进断点、
设置eclipse自动编译代码 处理tomcat不进断点问题 添加需要debug的项目 以上操作还是不行的话 可以把tomcat删除重新添加试试看
- java并发编程(一)线程状态 & 线程中断 & 线程间的协作
参考文章: Java线程的5种状态及切换:http://blog.csdn.net/pange1991/article/details/53860651 线程的5种状态: 1. 新建(NEW):新创建 ...
- 设计模式概要 & 六原则一法则
参考文章 http://blog.csdn.net/sinat_26342009/article/details/46419873 继承vs组合:http://www.cnblogs.com/feic ...