RSA原理及各种题型总结
Table of Contents
4,已知密文文件 flag.enc / cipher.bin /flag.b64和 公钥文件 pubkey.pem /key.pem /key.pub求解明文 m?
5,有私钥 private.pem 和密文 flag.enc
9,利用公钥pub.key/pub.pem文件生成 私钥文件
4.共模攻击(m,n相同;e,c不同,且e1 和 e2互质)
6,低加密指数广播攻击(模数n、密文c不同,明文m、加密指数e相同)
写在最前面
(文章中的所有python脚本,都是我在python3.7 / python2.7跑过,输出正常的脚本,如果你跑不出来,极可能是你环境的问题)
(文章中的每一个例题,虽是收集来的,但都动手操作过,实际求解出flag 后 再挂出来的)
要求的库包括但不限于:gmpy2、pycryptodome、libnum
gmpy2:https://pan.baidu.com/s/1De5h6XmkAuop69aYDiQ2gg 提取码: 6y2t
安装命令: pip3 install gmpy2-2.0.8-cp37-cp37m-win_amd64.whl
pycryptodome: pip3 install pycryptodome
libnum: pip3 install libnum
一,原理:
信息传递的过程:
-
A 要 向 B 传递信息 m
-
首先 B 要把 公钥 (n, e)传递给 A
-
然后 A 拿着公钥 进行 公钥加密算法 将 明文 m 变成 密文 c
-
接着 A 把 生成的 密文 c 传递 给 B
-
最后 B 再利用 私钥 (n,d)进行 私钥解密算法 还原出来 明文 m
rsa加密的过程:
- 随便找出两个 整数 q 和 p (q,p互素,即:公因数只有1)
- 求出n = q * p
- φ(n)= (p-1)*(q-1) 欧拉公式
- 公钥 e : 随机取,要求 :e 和 φ(n) 互素(公因数只有 1); 1< e < φ(n));
- 私钥 d : ed ≡ 1 (mod φ(n) ) (ed 除以 φ(n) 的 余数 为 1 )
加密算法:
解密算法:
还有一点必须要了解,就是 签名消息 其实就是一个校验码,确保密文在传播过程中没有被篡改过
签名消息(攻防世界中的一个题涉及到这个知识,所以在这里提一下)
RSA也可以用来为一个消息署名。假如Alice想给Bob传递一个署名的消息的话,那么她可以为她的消息计算一个散列值(Message digest),然后用她的私钥“加密”(如同前面“加密消息”的步骤)这个散列值并将这个“署名”加在消息的后面。这个消息只有用她的公钥才能被解密。Bob获得这个消息后可以用Alice的公钥“解密”(如同前面“解密消息”的步骤)这个散列值,然后将这个数据与他自己为这个消息计算的散列值相比较。假如两者相符的话,那么Bob就可以知道发信人持有Alice的私钥,以及这个消息在传播路径上没有被篡改过。
二,CTF 中的 常见的十种类型:
1,已知 p ,q,e 求 d?
(ed 除以 (q-1)(p-1) 的 余数 为 1 )
import gmpy2
p = 38456719616722997
q = 44106885765559411
e = 65537
s = (p-1)*(q-1)
d = gmpy2.invert(e,s)
print ("dec: " + str(d))
print ("hex: " + hex(d))
2,已知 n(比较小),e 求 d?
(n = q * p , ed 除以 (q-1)(p-1) 的 余数 为 1 )(n往往是一个 1024bit 的超大数,很难分解为两个 质数)
n的分解 用yafu 中的 factor(n )命令 (yafu kali自带,也有win版)
3,已知 公钥(n, e) 和 密文 c 求 明文 m?
方法一:(n,e不太大的情况下)
首先将 n 用 yafu分解为 q 和 p
再利用脚本 :
import libnum
from Crypto.Util.number import long_to_bytes
c = 0x6cd55a2bbb49dfd2831e34b76cb5bdfad34418a4be96180b618581e9b6319f86
n = 108539847268573990275234024354672437246525085076605516960320005722741589898641
#n = int("",16)
e = 65537
#e = int("",16)
q = 333360321402603178263879595968004169219
p = 325593180411801742356727264127253758939
d = libnum.invmod(e, (p - 1) * (q - 1))
m = pow(c, d, n) # m 的十进制形式
string = long_to_bytes(m) # m明文
print(string) # 结果为 b‘ m ’ 的形式
方法二:(n , e 比较大的时候)
直接利用 RsaCtfTool进行爆破:
利用 n,e生成公钥文件 test.pem:
python RsaCtfTool.py --createpub --n 46065781.... --e 3546111... > test.pub
再利用 下面的 使用 公钥爆破
4,已知密文文件 flag.enc / cipher.bin /flag.b64和 公钥文件 pubkey.pem /key.pem /key.pub求解明文 m?
方法一:(key.pem 和 cipher.bin)
直接用 RsaCtfTool进行破解:
python RsaCtfTool.py --publickey key.pem --uncipherfile cipher.bin
方法二:(flag.b64 和 key.pub)
先处理flag.b64(将flag.b64中的内容进行解 base64操作)
使用 notepad++ 打开 flag.b64文件使用 插件中的 MIME Tools 中的 base64 decode 将文件内容解密,然后另保存为 flag.enc 文件
然后使用 RsaCtfTool 工具进行破解:
python RsaCtfTool.py --publickey /root/desktop/share/key.pem --uncipherfile /root/desktop/share/flag.enc
方法三:
首先,提取 pubkey.pem 中的 参数:(openssl linux自带,win下也可以安装,具体openssl的用法自行百度)
一般能提取出来 n的值
openssl rsa -pubin -text -modulus -in warmup -in pubkey.pem
其次,用 yafu 分解 n 得到 q,p (win环境下)
yafu.exe factor(461616564564564654151561313213214659789765613131)
然后 制作 私钥 :生成私钥文件 private.pem
python rsatool.py -o private.pem -e 65537 -p 275127860351348928173285174381581152299 -q 319576316814478949870590164193048041239
最后 用private.pem文件 解密 flag.enc文件
openssl rsautl -decrypt -in flag.enc -inkey private.pem
5,有私钥 private.pem 和密文 flag.enc
方法一:利用 rsactftool。
python RsaCtfTool.py --private private.pem --uncipherfile flag.enc
方法二:利用 openssl:
openssl rsautl -decrypt -in flag.enc -inkey private.pem
6,已知c ,e,n(非常大),和 dp,dq,求解明文m
领航杯2019的一道题,EasyRSA:给了e, n, c,由于特别大,没法直接用质因数分解求得 q, p
还给了 phint = d % (p - 1) 其实 phint = dp
qhint = q % (p - 1) 其实 qhint = dq
(2019山东省赛“深思杯”中 被加密的消息 一题 跟本题 的思路一样)
import gmpy2
import libnum
e=65537
n=16969752165509132627630266968748854330340701692125427619559836488350298234735571480353078614975580378467355952333755313935516513773552163392952656321490268452556604858966899956242107008410558657924344295651939297328007932245741660910510032969527598266270511004857674534802203387399678231880894252328431133224653544948661283777645985028207609526654816645155558915197745062569124587412378716049814040670665079480055644873470756602993387261939566958806296599782943460141582045150971031211218617091283284118573714029266331227327398724265170352646794068702789645980810005549376399535110820052472419846801809110186557162127
dp=1781625775291028870269685257521108090329543012728705467782546913951537642623621