前言

今天,手一抽打开了这个网站并注册登录

0

(一个早上看奥运会碌碌无为

我想就顺便试试水吧)

1

先做的是easy_RSA,已经把d算出来了,可是提交显示不对..仔细看了题目的要求后..说:flag格式为cyberpeace{小写的你解出的答案}。我以为这是把答案转化成cyberpeace格式…上网搜索“在线cyberpeace转化”未果,才知道原来答案要带上这一串英文啊..

2

然后,我又手一抽,点到了下一题..然鹅计时已经开始

5

7

6

啊?都是乱码,没有n,e,c咋解呢这

于是乎,复制了BEGIN PRIVATE KEY到浏览器搜索,顺其自然地开始了我对rsa公钥文件解密的study(

解密

提n,e

这时候我们有如下的publickey.pem文件:

——-BEGIN PUBLIC KEY——-
MDwwDQYJKoZIhvcNAQEBBQADKwAwKAIhAMJjauXD2OQ/+5erCQKPGqxsC/bNPXDr
yigb/+l/vjDdAgMBAAE=
——-END PUBLIC KEY——-

现在我们需要做的就是从这段字符串中提出n和e

pem后缀

OpenSSL 使用 PEM 文件格式存储证书和密钥。PEM 实质上是 Base64 编码的二进制内容,再加上开始和结束行,如证书文件的:

1
2
3
-----BEGIN CERTIFICATE-----`

`-----END CERTIFICATE-----

在这些标记外面可以有额外的信息,如编码内容的文字表示。文件是 ASCII 的,可以用任何文本编辑程序打开它们。

简单来讲,pem文件这种格式就是用于ASCII(Base64)编码的各种X.509 v3 证书。所以我们用base64解码

base64编码

从一个表格中了解base64的发展

名称 缺点 特点
二进制 简单,0和1
Hex(16进制 不好表示文本
ASCLL码 只能表示英文 包含字符多
UTF-8 乱码 兼容各种语言
Base-64 国际化

用base64解码:

乱码

解出来是一段乱码,旁边有个可以以15进制显示的选项,我们试一下

16进制

发现结尾是”\x01\x00\x01”,猜测e=10001

再看看解码后的长度为162,我们找到偏移表,发现模数的偏移位置是159,长度是3,加起来正好162~那么说明这段字符串就是指数和模数加密过后的结果。

Snipaste_2021-07-24_21-45-30

解e和n

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# -*- coding: utf-8 -*-

import base64

def str2key(s):
# 对字符串解码
b_str = base64.b64decode(s)

if len(b_str) < 162:
return False

hex_str = ''

# 按位转换成16进制
for x in b_str:
h = hex(ord(x))[2:]
h = h.rjust(2, '0')
hex_str += h

# 找到模数和指数的开头结束位置
m_start = 29 * 2
e_start = 159 * 2
m_len = 128 * 2
e_len = 3 * 2

modulus = hex_str[m_start:m_start + m_len]
exponent = hex_str[e_start:e_start + e_len]

return modulus,exponent

if __name__ == "__main__":

pubkey = "MDwwDQYJKoZIhvcNAQEBBQADKwAwKAIhAMJjauXD2OQ/+5erCQKPGqxsC/bNPXDr
yigb/+l/vjDdAgMBAAE="
key = str2key(pubkey)
print key

结果如下:

1
('C2636AE5C3D8E43FFB97AB09028F1AAC6C0BF6CD3D70EBCA281BFFE97FBE30DD', '010001')

这个即为我们求出来模数N和指数e

网上说可以用虚拟机Kali Linux直接用命令

1
openssl rsa -pubin -text -modulus -in warmup -in pubkey.pem

试了下,确实很方便

屏幕截图 2021-07-24 210147

我们把n=C2636AE5C3D8E43FFB97AB09028F1AAC6C0BF6CD3D70EBCA281BFFE97FBE30DD,e=10001(十六进制)在线转化十进制

进制转换 - 在线工具 (tool.lu)

进制转化

n

所以e=65537``n=87924348264132406875276140514499937145050893665602592992418171647042491658461

得到n,e后就是常规的做题啦

分解n得pq

解码网址上篇也有用到http://www.factordb.com/

搜狗截图20210724204727

p = 275127860351348928173285174381581152299

q = 319576316814478949870590164193048041239

求d

走个Python执行结果

1
2
3
4
5
6
7
import gmpy2 
p= gmpy2.mpz(275127860351348928173285174381581152299)
q= gmpy2.mpz(319576316814478949870590164193048041239)
e= gmpy2.mpz(65537)
phi_n= (p-1)*(q-1)
d = gmpy2.invert(e,phi_n)
print("d is:\n%s"%d)

结果d=10866948760844599168252082612378495977388271279679231539839049698621994994673

d

求m

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import gmpy2
import rsa

e=65537
n=87924348264132406875276140514499937145050893665602592992418171647042491658461
p=275127860351348928173285174381581152299
q=319576316814478949870590164193048041239
d=10866948760844599168252082612378495977388271279679231539839049698621994994673


key=rsa.PrivateKey(n,e,int(d),p,q)

with open(r"C:\Users\Lenovo\Desktop\0eaf8d6c-3fe5-4549-9e81-94ac42535e7b\flag.enc","rb")as f:
f=f.read()
print(rsa.decrypt(f,key))

o

总结

给出的文件不一定直接给出数字,有时候需要先解码(像这题),提取关键字眼,间接求数字。

有时Python比虚拟机操作繁琐。

一些编码的类型要识别出来(比如base64,hex)

能直接利用网站在线求解的不需要写Python