题目描述:
两个文件,都用记事本打开,记住用记事本打开
pub.key:
-----BEGIN PUBLIC KEY-----
MDwwDQYJKoZIhvcNAQEBBQADKwAwKAIhAMAzLFxkrkcYL2wch21CM2kQVFpY9+7+
/AvKr1rzQczdAgMBAAE=
-----END PUBLIC KEY-----
flag.enc:
A柪YJ^
柛x秥?y[蔜?旭?緃沚
题目分析:
- 显然第一个文件即时普通的公钥(n,e)解密文件,第二个文件是密文c解密文件,与
buu [AFCTF2018]可怜的RSA 1 和 buu [HDCTF2019]together 1 很像 - 公钥解密按套路来,可以用线上工具,也可以用脚本
1.线上公钥解析网站:
2.代码解密(将代码文件和 pub.key文件 放同一个文件夹):
from Crypto.PublicKey import RSA
with open('pub.key','rb') as f:
key = RSA.import_key(f.read())
print(key.n)
print(key.e)
- 得到:
n = 86934482296048119190666062003494800588905656017203025617216654058378322103517
e = 65537
- n 分解得 p,q:
p = 285960468890451637935629440372639283459
q = 304008741604601924494328155975272418463
- 最终便是求密文了,遇到此种一段乱码的直接用python脚本(记住就好,不必深究,挺简单的,记住将代码文件和 flag.enc文件 放同一个文件夹):
with open('flag.enc','rb') as f:
print(libnum.s2n(f.read()))
- 最终得到密文c:
c = 29666689760194689065394649908301285751747553295673979512822807815563732622178
- 自此,所有未知数都已求出,完整代码如下:
from Crypto.PublicKey import RSA
import gmpy2
import libnum
# with open('pub.key','rb') as f:
# key = RSA.import_key(f.read())
# print(key.n)
# print(key.e)
n = 86934482296048119190666062003494800588905656017203025617216654058378322103517
e = 65537
p = 285960468890451637935629440372639283459
q = 304008741604601924494328155975272418463
# with open('flag.enc','rb') as f:
# print(libnum.s2n(f.read()))
c = 29666689760194689065394649908301285751747553295673979512822807815563732622178
phi = (p-1)*(q-1)
d = gmpy2.invert(e,phi)
m = pow(c,d,n)
print(libnum.n2s(int(m)))
- 得到 flag{decrypt_256}
收获与体会:
- 对于求公钥私钥的套路我们已了解,那么接下来我们来总结此种题型下求密文的方法(至今知道的有三种):
1.密文出现一段乱码的用以下代码:
with open('flag.enc','rb') as f:
print(libnum.s2n(f.read()))
2.密文出现一串类似base64的字符串的有一下两种:
(1)第一种:
f1="R3Noy6r3WLItytAmb4FmHEygoilucEEZbO9ZYXx5JN03HNpBLDx7fXd2fl+UL5+11RCs/y0qlTGURWWDtG66eNLzGwNpAKiVj6I7RtUJl2Pcm3NvFeAFwI9UsVREyh7zIV6sI9ZP8l/2GVDorLAz5ULW+f0OINGhJmZm8FL/aDnlfTElhQ87LPicWpXYoMtyr6WrxjK6Ontn8BqCt0EjQ7TeXZhxIH9VTPWjDmFdmOqaqdVIT+LZemTgLNESwM5nn4g5S3aFDFwj1YiDYl0/+8etvKfOrfoKOwR0CxsRHagwdUUTES8EcHLmMGCxCkDZn3SzmmA6Nb3lgLeSgG8P1A=="
f2="O+rRCXI3aTB6P1rYIOPUdalUp6ujpwEq4I20CoWA+HIL8xxGtqY6N5gpr0guZv9ZgOEAMFnBxOqMdVNnB9GgnhmXtt1ZWydPqIcHvlfwpd/Lyd0XSjXnjaz3P3vOQvR71cD/uXyBA0XPzmnTIMgEhuGJVFm8min0L/2qI7wg/Z7w1+4mOmi655JIXeCiG23ukDv6l9bZuqfGvWCa1KKXWDP31nLbp0ZN2obUs6jEAa1qVTaX6M4My+sks+0VvHATrAUuCrmMwVEivqIJ/nS6ymGVERN6Ohnzyr168knEBKOVj0FAOx3YLfppMM+XbOGHeqdKJRLpMvqFXDMGQInT3w=="
c1 = bytes_to_long(base64.b64decode(f1)) # base64转字节后再转整数
c2 = bytes_to_long(base64.b64decode(f2)) # base64转字节后再转整数
(2)第二种(此种情况可在使用第一种方式下得不到答案的情况下使用,很特殊的一种方式):
import base64
from Crypto.Cipher import PKCS1_OAEP
key = RSA.construct((n, e, d, p, q))
key = RSA.importKey(key.exportKey())
key = PKCS1_OAEP.new(key)
f = 'GVd1d3viIXFfcHapEYuo5fAvIiUS83adrtMW/MgPwxVBSl46joFCQ1plcnlDGfL19K/3PvChV6n5QGohzfVyz2Z5GdTlaknxvHDUGf5HCukokyPwK/1EYU7NzrhGE7J5jPdi0Aj7xi/Odxy0hGMgpaBLd/nL3N8O6i9pc4Gg3O8soOlciBG/6/xdfN3SzSStMYIN8nfZZMSq3xDDvz4YB7TcTBh4ik4wYhuC77gmT+HWOv5gLTNQ3EkZs5N3EAopy11zHNYU80yv1jtFGcluNPyXYttU5qU33jcp0Wuznac+t+AZHeSQy5vk8DyWorSGMiS+J4KNqSVlDs12EqXEqqJ0uA=='
c = base64.b64decode(f)
flag = key.decrypt(c)
print(flag)