Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
277 changes: 277 additions & 0 deletions Cry/submissions/24-Cry-Tak3-王海琰.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,277 @@
> ID:Tak3
>
> 方向:misc
>
> 日期:2026-04-19

# 1. 基础知识

## 1.1. 质数

又称素数,是指在大于$1$的自然数中,除了$1$和它本身以外不再有其他因数的的自然数。

## 1.2. 合数

合数可以看作由两个或多个素数相乘得到。

- 对于任意合数$n$,存在$s$个两两不同的素数$p_1,p_2,p_3,\cdots,p_s$,使得$n=p_1\times p_2\times p_3\times\cdots\times p_s$。

## 1.3. 欧拉函数$\varphi(n)$

- $\varphi(n)$是从$1$到$n$中,与$n$互素(即$gcd(i,n)=1$)的整数$\boldsymbol{i}$的个数。


- 若$n$是素数,则$1,2,...,n-1$均与$p$互素,所以有$\varphi(n)=n-1$。

- 若$n$是由均为一次幂的两两不同的质数相乘所得的合数,即$n=p_1\times p_2\times p_3\times\cdots\times p_s$,则有$\varphi(n)=(p_1-1)\times(p_2-1)\times(p_3-1)\times\cdots\times(p_s-1)$。

- 从$1$到$n$共有$n$个数

- $p_{1}$的倍数:$1p_1,2p_1,...,p_1p_2p_3\cdot\cdot\cdot p_s$,共有$p_2p_3\cdots p_s$个

- $p_{2}$的倍数:$1p_2,2p_2,...,p_1p_2p_3\cdots p_s$,共有$p_1p_3\cdots p_s$个

- $p_{3}$的倍数:$1p_3,2p_3,...,p_1p_2p_3\cdots p_s$,共有$p_1p_2\cdots p_s$个

- 依次类推......

- $\varphi(n)$本质上求的是从$1$到$n$这从$n$个数中与$n=p_1\times p_2\times p_3\times\cdots\times p_s$互质的数的个数,所以有$\varphi(n)=n-(p_2p_3\cdots p_s)-(p_1p_3\cdots p_s)-(p_1p_2\cdots p_s)-\cdots-(p_1p_2p_3\cdots p_{s-1})=(p_1-1)(p_2-1)(p_3-1)\cdots(p_{s-1}-1)$

- 若$n$是合数且其因子存在素数的多次幂,即$n=p_{1}^{k_{1}}\times p_{2}^{k_{2}}\times p_{3}^{k_{3}}\times\cdots\times p_{s}^{k_{s}}$,则有$\varphi(n)=\left[p_1^{k_1}\left(1-\frac{1}{p_1}\right)\right]\times\left[p_2^{k_2}\left(1-\frac{1}{p_2}\right)\right]\times\cdots\times\left[p_s^{k_s}\left(1-\frac{1}{p_s}\right)\right]=n\prod_{i=1}^s\left(1-\frac{1}{p_i}\right)$计算原理同上。

# 2. RSA

## 2.1. 概念

RSA 加密算法是一种非对称加密算法。

非对称加密算法:一种安全的数据加密方法,它使用一对密钥:公钥和私钥。公钥可以公开分享,而私钥必须保密。如果使用公钥加密数据,只有对应的私钥才能解密;反之亦然。这种加密方式因为使用了两个不同的密钥,因此被称为非对称加密。

RSA 算法的可靠性由极大整数因数分解的难度决定。

## 2.2. 基本原理

### 2.2.1. 生成密钥

1. 定义明文$m$、密文$c$
2. 选两个大素数$p$和$q$
3. 计算$n=p\times q$
4. 计算欧拉函数$\varphi(n)=(p-1)(q-1)$
5. 选一个与$\varphi(n)$互素的整数$e$
6. 计算得到$e$模为$\varphi(n)$的逆元$d$,使得有$e\times d\equiv1({\mathrm{mod}}\varphi(n))$

### 2.2.2. 加密与解密

1. 加密:$c=m^e({\mathrm{mod~}}n)$
2. 解密:$c=m^d({\mathrm{mod~}}n)$

由此可以衍生出各种各样的 RSA 题的变体。

# 3. WriteUp

## 3.1 eeeeez_rsa

### Task

```python
from Crypto.Util.number import *
from secrets import randbits

p = getPrime(512)
q = getPrime(512)

n = p * q
e = 65537

m = bytes_to_long(flag)

c = pow(m, e, n)

print("p =", p)
print("q =", q)
print("e =", e)
print("c =", c)
'''
p = 7833526559350210716763736624276871338973265302039384005037668270722459749111510212645578582715412039060908556429504391788904499303021963918033838457712021
q = 11274522482114648167653425707657117942167215969612324249057858493398092816663094339833695146914712716091767834292452373966791325922322967827879446489910963
e = 65537
c = 10221721591889545844573050254595795861182348856506145605480348246534477032085113801390383245391427274224627900490105787486227774188957450006691363974396952878850785124275814042623413354128640305152567667226654321244510669777870256213487113315863197287562256336752636572876416053482569293397021584043886350655
'''
```

### Analysis

p 和 q 已知,利用欧拉函数求出 φ(n),进而计算出 e 模 φ(n) 的逆元 d,由`m = pow(c,d,n)`求出明文,最终获得 flag。

### EXP

```python
import gmpy2
from Crypto.Util.number import long_to_bytes

p=7833526559350210716763736624276871338973265302039384005037668270722459749111510212645578582715412039060908556429504391788904499303021963918033838457712021
q=11274522482114648167653425707657117942167215969612324249057858493398092816663094339833695146914712716091767834292452373966791325922322967827879446489910963
e=65537
c=10221721591889545844573050254595795861182348856506145605480348246534477032085113801390383245391427274224627900490105787486227774188957450006691363974396952878850785124275814042623413354128640305152567667226654321244510669777870256213487113315863197287562256336752636572876416053482569293397021584043886350655

phi_n = (p-1)*(q-1)
d = gmpy2.invert(e,phi_n)
m = pow(c,d,p*q)
print(long_to_bytes(m))

# b'flag{W31c0m3_T0_Crypt0}'
```

从而得到 flag:`flag{W31c0m3_T0_Crypt0}`

## 3.2 What is dpdq

### Task

```python
from Crypto.Util.number import *

p = getPrime(512)
q = getPrime(512)

n = p * q

m = bytes_to_long(flag)

c = pow(m, e, n)

phi = (p - 1) * (q - 1)
d = inverse(e, phi)

dp = d % (p - 1)
dq = d % (q - 1)

print("p =", p)
print("q =", q)
print("dp =", dp)
print("dq =", dq)
print("c =", c)
'''
p = 7815414185491141116816659592648655093824828684096724566017773298150863675227130435782645950134326106977982747903113904523205447790009729530724322503221833
q = 9989016009119164140172559452397593815416653032520645020530362343604703571290641132626496035194681031089349635895258123948622879868985300264027551088746747
dp = 4010681140217557380422935065992638785960856284290416720391683347779267392850433355451759290094414691393922757792964689212573746434435619933431808206484225
dq = 2650091114188243387783699150080671432452650354401886796343461099352350290584408461982954461814393687345324352950407449243857759926179828428073409383707519
c = 49442655923625309909385017545371837339079019962533687954830521594031788193892512818961352203881969632046490177930759665200677302956816647378151364853230118743634390053041583940566732297636464662866406886764229490729837423276227228984024967061624432225315562131278455141688731687433597958272776740673914705069
'''
```

### Analysis

本题属于 dp,dq 泄露

> 原本 dp 和 dq 的作用是用来加快加解密速度的,但是由于dp和p,dq和q的关系密切,一旦泄漏,将造成很大的安全隐患

原理推导:
$$
\begin{aligned}
&\begin{cases}
d \equiv d_p \pmod{p-1} \quad (1) \\
d \equiv d_q \pmod{q-1} \quad (2) \\
\end{cases} \\

&\text{由(2):} \\
&d = k(q-1) + d_q \quad (3) \\

&\text{将(3)带入(1):} \\
&k(q-1) + d_q \equiv d_p \pmod{p-1} \\

&k(q-1) \equiv d_p - d_q \pmod{p-1} \\

&k \equiv (d_p - d_q)(q-1)^{-1} \pmod{p-1} \quad (4) \\

&\text{将(4)代入(3):} \\
&d = \left[ (d_p - d_q)(q-1)^{-1} \bmod (p-1) \right](q-1) + d_q \\

&= d_q + (q-1)\left( \left( (d_p - d_q)(q-1)^{-1} \right) \bmod (p-1) \right)
\end{aligned}
$$

### EXP

```python
import gmpy2
from Crypto.Util.number import long_to_bytes

p = 8637633767257008567099653486541091171320491509433615447539162437911244175885667806398411790524083553445158113502227745206205327690939504032994699902053229
q = 12640674973996472769176047937170883420927050821480010581593137135372473880595613737337630629752577346147039284030082593490776630572584959954205336880228469
dp = 6500795702216834621109042351193261530650043841056252930930949663358625016881832840728066026150264693076109354874099841380454881716097778307268116910582929
dq = 783472263673553449019532580386470672380574033551303889137911760438881683674556098098256795673512201963002175438762767516968043599582527539160811120550041
c = 24722305403887382073567316467649080662631552905960229399079107995602154418176056335800638887527614164073530437657085079676157350205351945222989351316076486573599576041978339872265925062764318536089007310270278526159678937431903862892400747915525118983959970607934142974736675784325993445942031372107342103852

q_inv=gmpy2.invert(q,p)
mp=pow(c,dp,p)
mq=pow(c,dq,q)
m=(((mp-mq)*q_inv)%p)*q+mq

print(long_to_bytes(m))

#b'noxCTF{W31c0m3_70_Ch1n470wn}'
```

从而得到 flag:`noxCTF{W31c0m3_70_Ch1n470wn}`

## 3.3 three

### Task

```python
import libnum
import gmpy2
import uuid
flag = "flag{" + str(uuid.uuid4()) + "}"
m = libnum.s2n(flag)
print(gmpy2.bit_length(m ** 3))
while True:
p = libnum.generate_prime(504)
q = libnum.generate_prime(504)
n = p * q
phi_n = (p - 1) * (q - 1)
e = 3
if gmpy2.gcd(e, phi_n) == 1 and phi_n%e !=0:
break

c = pow(m, e, n)
print("n=", n)
print("e=", e)
print("c=", c)
'''
n= 1429271935073130420990643850236689595291596400638807867713275629712107176185520444788761901754075622136449476721042807647099083589759664014467696405646188198112649666177678289522724798981531832903351705482763333352669597586657968404428319154104297454666647063679624028208478294081894177792365782518110223
e= 3
c= 175676150266632261170048224865383344382701466592480820852821987310883907646453945269873798553604154950679789706816103734968119191264040967221804258086782193045472222806462922151478555259607753533988574525462498108797766467552606740700525351657072574897006690469089852849417334378963664086027896356417125
'''
```

### Analysis

本题属于低加密指数攻击。尝试运行该程序,发现 m^e(即 m^3)的小于 n,说明生成 c 时实际上并未发生取余,即 c=m^e。那么要想求 m,只需对 c 开 e=3 次方根再转为字符串即可。

### EXP

```python
import gmpy2
import libnum

c = 175676150266632261170048224865383344382701466592480820852821987310883907646453945269873798553604154950679789706816103734968119191264040967221804258086782193045472222806462922151478555259607753533988574525462498108797766467552606740700525351657072574897006690469089852849417334378963664086027896356417125

m, exact = gmpy2.iroot(c, 3)

if exact:
print(libnum.n2s(int(m)))

#b'flag{d07cc7cf-9d78-4bfb-9449-d099b0329563}'
```

从而得到 flag:`flag{d07cc7cf-9d78-4bfb-9449-d099b0329563}`

# 4. Sagemath

![img](https://cdn.nlark.com/yuque/0/2026/png/65087184/1776519974389-23a18ca2-afae-4357-90c6-23e1998071cf.png)

# 5. 选择 Crypto 的原因

上一学期学了信息安全数学基础这门课,感觉这个方向跟这门课很贴近,所以想试试看 。
Loading