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 ...
随机推荐
- 前端jsp fetch跨域调用 is not allowed by Access-Control-Allow-Origin.
之前我在用json跨域调用时,遇到如图问题,后来查查是官方json不支持跨域调用,后来改用非官方的jsonp跨域调用后台方法,出现如下问题 Origin http://127.0.0.1:8080 i ...
- [译] 2017 年比较 Angular、React、Vue 三剑客
原文地址:Angular vs. React vs. Vue: A 2017 comparison 原文作者:Jens Neuhaus 译文出自:掘金翻译计划 本文永久链接:github.com/xi ...
- 硬币游戏2&&Cutting Game——Grundy值
Grundy值 当前状态的Grundy值就是除任意一步所能转移到的状态的Grundy值以外的最小非负整数, 以硬币问题一为例,可写成: int init_grundy() { sg[] = ; ;i ...
- LeetCode 286. Walls and Gates
原题链接在这里:https://leetcode.com/problems/walls-and-gates/ 题目: You are given a m x n 2D grid initialized ...
- VirtualBox support USB3.0 funciton
首先确认Oracle VM VirtualBox 的版本 然后通过如下链接下载对应的扩展增强包: http://download.virtualbox.org/virtualbox 再则,通过管理-& ...
- Numpy | 05 创建数组
ndarray 数组除了可以使用底层 ndarray 构造器来创建外,也可以通过以下几种方式来创建. 一.numpy.empty numpy.empty 方法用来创建一个指定形状(shape).数据类 ...
- where与having 的区别
二者的区别在于作用对象不同. where子句作用于基本表或视图,从中选择满足条件的一行或多行元祖. having短语作用于组,从中选择满足条件的组.这些组应该由group by 短句来进行分组.
- nave node 的虚拟环境管理工具
nave 是类似python venv 的node 虚拟环境管理工具 安装 npm install -g nave 简单使用 帮助命令 Usage: nave <cmd> Commands ...
- AcWing 95 费解的开关
目录 前言 题目链接 思路 代码 前言 博客咕咕咕了好久了,是时候写一下了 题目链接 AcWing 95 费解的开关 思路 首先可以看出 1.每一个位置顶多只会操作一次.因为如果操作两次的话,相当于不 ...
- Linux里使用rz和sz命令
lrzsz是一个unix通信套件提供的X,Y,和ZModem文件传输协议,官网:http://freecode.com/projects/lrzsz/ windows 需要向centos服务器上传文件 ...