今天整理一波我的做题思路和代码
题目描述
一个flag.encrypt文件(rsa加密的文件)
一个pubkey.key文件(rsa的公钥)
解题思路和过程
RSA问题依赖于大整数分解问题,只要模数n能分解,就可以通过公钥破解密文。
第一步:从公钥中获取模数n和指数e
首先需要安装OpenSSL,网上下载安装即可,不需要安装其他东西。
在 OpenSSL的安装路径\bin 下找到openssl.exe文件,点击openssl.exe文件,进入openssl终端。
在openssl终端输入:rsa -pubin -text -modulus -in warmup -in pubkey.pem,这里用的是私钥的相对路径。
或者在windows的cmd命令窗口执行:openssl rsa -pubin -text -modulus -in warmup -in pubkey.pem,这里用的是私钥的绝对路径。
我们可以看到,Modulus(模数n)、Exponent(指数e)已经被分离出来。可以看到:
n=C2636AE5C3D8E43FFB97AB09028F1AAC6C0BF6CD3D70EBCA281BFFE97FBE30DD
指数e是65537。
用在线工具把模数转化为10进制,或者用python输出10进制。我采用的在线工具是:https://tool.lu/hexconvert/,或者用Python求解,得到n=87924348264132512606026244266860026602226062424884468222066668822204828484286
#coding:utf8
modulus ="C2636AE5C3D8E43FFB97AB09028F1AAC6C0BF6CD3D70EBCA281BFFE97FBE30DD"
n = int (modulus,16)
print(n)
# 运行结果
# 87924348264132406875276140514499937145050893665602592992418171647042491658461
第二步:大整数分解(分解n),获取p和q
第二步需要将n分解为两个质数(p和q的成绩),通过在线工具https://factordb.com/进行大整数分解。得到:
p = 275127860351348928173285174381581152299
q = 319576316814478949870590164193048041239
第三步:计算RSA的d
ed ≡ 1( mod r)
r = φ(q)*φ(p)=(q-1)*(p-1) 这里的φ是欧拉函数。
计算d的python代码实现:
#coding -*- utf:8 -*-
#如果没有rsa,在cmd窗口执行:pip install rsa
import rsa
def egcd(a, b):
if a == 0:
return (b, 0, 1)
else:
g, y, x = egcd(b % a, a)
return (g, x - (b // a) * y, y)
def modinv(a, m):
g, x, y = egcd(a, m)
if g != 1:
raise Exception('modular inverse does not exist')
else:
return x % m
if __name__=='__main__':
p = 275127860351348928173285174381581152299
q = 319576316814478949870590164193048041239
N = 87924348264132406875276140514499937145050893665602592992418171647042491658461
e = 65537
d = modinv(e,fn)
print(d)
# 运行结果
# d = 10866948760844599168252082612378495977388271279679231539839049698621994994673
第四步:计算RSA的私钥
计算RSA的私钥的时候,需要在python中导入Crypto,python3安装Crypto是一个巨坑。。。
首先需要下载:pycrypto python3.6 whl(https://download.csdn.net/download/fzwolfcub/10173046,需要五个积分,肉疼,用的学姐的积分,学姐会不会打我,亲测可用)
安装:进入cmd命令窗口,执行 pip3 install pycrypto-2.6.1-cp36-cp36m-win_amd64.whl
安装后可能会遇见ModuleNotFoundError: No module named ‘winrandom’ 等问题,这里提供一个链接供参考:https://blog.csdn.net/liujingqiu/article/details/79109131
贴出生成私钥的python代码:
# coding=utf-8
from Crypto.PublicKey import RSA
keypair = RSA.generate(1024)
keypair.p = 275127860351348928173285174381581152299
keypair.q = 319576316814478949870590164193048041239
keypair.e = 65537
keypair.d = 10866948760844599168252082612378495977388271279679231539839049698621994994673
keypair.n = 87924348264132406875276140514499937145050893665602592992418171647042491658461
private_str = keypair.exportKey()
print(private_str)
# 输出结果
# b'-----BEGIN RSA PRIVATE KEY-----\nMIGqAgEAAiEAwmNq5cPY5D/7l6sJAo8arGwL9s09cOvKKBv/6X++MN0CAwEAAQIg\nGAZ5m9RM5kkSK3i0MGDHhvi3f7FZPghC2gY7oNhyi/ECEQDO+7LPfhipjr7cNuPn\nw7ArAhEA8Gwo6RyJIrnCNuI1YMCXFwIRAJulRkclqWIHx5pNZIAp9VUCEGjeJLIZ\nek+lSut5m+LJ3p0CEDRBEd7C622/wt1+58xOIfE=\n-----END RSA PRIVATE KEY-----'
最后产生私钥文件
# coding=utf-8
str = "-----BEGIN RSA PRIVATE KEY-----\nMIGqAgEAAiEAwmNq5cPY5D/7l6sJAo8arGwL9s09cOvKKBv/6X++MN0CAwEAAQIg\nGAZ5m9RM5kkSK3i0MGDHhvi3f7FZPghC2gY7oNhyi/ECEQDO+7LPfhipjr7cNuPn\nw7ArAhEA8Gwo6RyJIrnCNuI1YMCXFwIRAJulRkclqWIHx5pNZIAp9VUCEGjeJLIZ\nek+lSut5m+LJ3p0CEDRBEd7C622/wt1+58xOIfE=\n-----END RSA PRIVATE KEY-----"
private = open('private.pem','w')
private.write(str)
private.close()
最后就会在python的默认路径下生成private.pem文件
第五部:解密密文
看着很顺利,最蛋疼的部分是我在openssl,用私钥解密密文的时候会报错,如下图。
这是为什么呢,这是为什么呢,这是因为python生成的私钥是没有填充的,所以要用无填充的方式进行解密,正确的方法如下:
成功了,感动,就是在最后添加了 -raw,指明了私钥是没有填充的。
打开得到的flag.de文件。得到的是:
???这是啥,很明显的16进制,然后解码就ok了(在线解码就行)。
flag{Y0u_m4y_uNd3rstand_RSA}