密码学(Crypto)梳理(一)

一、数论基础

1 欧拉定理

a^φ(n) ≡ 1 (mod n)

这个解释一下 ≡ 符号的含义

复制代码
17≡5(mod12)
表明17和5除以12的余数相同
17 ÷ 12 = 1 余 5
5 ÷ 12 = 0 余 5
余数一样,所以同余

φ(n) 就是 1 到 n-1 中与 n 互质的整数个数

复制代码
比如n =12 ,则 1 到 n-1 中与 n 互质的数有 1 5 7 11
 所以 φ(n)=4
欧拉定理:

定理:若 gcd(a, n) = 1,则 a^φ(n) ≡ 1 (mod n)。

想了想还是觉得直接带入数容易理解

复制代码
a=7 n=12
φ(12)=4
a^φ(n)=2401
a^φ(n) mod n = 1   

所以欧拉定理验证:
7^4 mod 12 = 1 = 1 
φ(12)=4
gcd(7,12)=1
定理成立
从欧拉定理到 RSA:完整的数学推导

RSA 的正确性就是一句话:加密后解密能还原明文

复制代码
(m^e)^d ≡ m (mod n)

分析RSA:

n = p×q(p,q 为不同质数),

φ(n) = (p-1)(q-1),

ed ≡ 1 (mod φ(n))

即存在整数 k,使得 ed = 1 + k·φ(n)

对任意明文 m(gcd(m,n)=1),有 m^(ed) ≡ m (mod n),意味着加密后再解密,能完整还原原始信息

带入数分析

复制代码
p=11  q=13  e=7 
明文 m = 5

密钥生成
n = 11×13 = 143
φ(n) = (11-1)×(13-1) = 10×12 = 120
e = 7(公钥指数,gcd(7,120)=1 )
d = e⁻¹ mod φ(n) = 103(私钥,由扩展欧几里得求得)
验证:e×d = 7×103 = 721 = 1 + 6×120 ✓


这里补充一下模逆元知识,在rsa中经常用到
 7⁻¹ mod 120 
 意思是可以设一个未知数下x   7x ≡ 1(mod120)
 要求 7x+120y=1
 由欧几里得算法得到
 1=(−17)⋅7+1⋅120
 7x+120y=1
 所以x = -17
 转成正数(模运算标准写法)
 −17mod120=103
 
加密过程
c = m^e mod n = 5^7 mod 143 = 47

解密过程
m' = c^d mod n = 47^103 mod 143 = 5

2 费马小定理

费马小定理和 Miller-Rabin 是密码学里质数生成的核心工具------RSA 需要生成两个大质数,而验证一个 1024 位的数是否为质数,靠的就是 Miller-Rabin。

费马小定理

定理内容:若 p 是质数,且 gcd(a, p) = 1,则 a^(p-1) ≡ 1 (mod p)。

复制代码
a=3 p=7
p=7 是质数,所有底数的 a^(p-1) ≡ 1 (mod p),定理完全成立。

费马测试的缺陷:Carmichael 数

费马测试的逻辑是:如果 a^(p-1) mod p ≠ 1,则 p 必然是合数,但反过来不成立

有极少数合数(Carmichael 数,如 561、1105、1729)对所有与它互质的底数都满足 a^(p-1) ≡ 1,费马测试完全看不穿它们。

Miller-Rabin 就是为了解决这个漏洞而设计的。

Miller-Rabin 算法

核心思路:把 p-1 写成 2^s × d(d 是奇数),然后不只检验最终结果,而是检验整个"平方根链"的行为。

若 p 是质数,则 x² ≡ 1 (mod p) 的解只有 x ≡ ±1。所以在反复平方的过程中,如果哪一步突然从"非 ±1"跳到了 1,那 p 必然是合数。

复制代码
n=561
底数a = 2,3,5
第一步:将 n-1 分解为 2^s × d
n-1 = 560 = 2^4 × 35  s = 4,d = 35(d 是奇数)  检测链长度:4 步平方

逐轮检测(每个底数一轮)
底数 a = 2   合数!
263→166→67→1
平方后出现 1,但前一个值不是 ±1 → 合数

底数 a = 3   合数!
78→474→276→441
所有平方均未出现 n-1 → 合数

底数 a = 5   合数!
23→529→463→67
所有平方均未出现 n-1 → 合数

n = 561(Carmichael 数):费马测试的死穴,但 Miller-Rabin 用底数 2 仍能检出

在 RSA 密钥生成中的实际用法

RSA 需要生成两个大质数 p 和 q(各约 1024 位)。

实际流程是:随机生成一个奇数 → 用 Miller-Rabin 测试 → 通过则使用,否则换下一个候选数。

3 中国剩余定理(CRT)

CRT 是密码学里少见的"既有理论美感、又有工程价值"的定理。我们先从直觉出发,再走一遍完整的数学机制,最后看它如何让 RSA 解密快 4 倍。

直觉:用多个"余数指纹"唯一定位一个数

想象你要在 1 到 105 之间猜一个数,我只告诉你三个线索:它除以 3 余 2,除以 5 余 3,除以 7 余 2。CRT 说:这三条线索足以唯一确定这个数。

则 x = 23

CRT 的构造公式分四步。

1 计算乘积 N = n₁ × n₂ × n₃

N = 3 × 5 × 7 = 105

N 是解存在的范围,唯一解 x ∈ [0, 105)

2 计算各 Nᵢ = N / nᵢ(去掉第 i 个模数后的乘积)

3 35 105÷3=35,被 n₂n₃ 整除

5 21 105÷5=21,被 n₁n₃ 整除

7 15 105÷7=15,被 n₁n₂ 整除

3 用扩展欧几里得算法求各 yᵢ = Nᵢ⁻¹ mod nᵢ

35⁻¹ mod 3 2

21⁻¹ mod 5 1

15⁻¹ mod 7 1

4 合并:x = Σ rᵢ · Nᵢ · yᵢ (mod N)

x = 2×35×2 + 3×21×1 + 2×15×1 mod 105

= 140 + 63 + 30 mod 105

= 233 mod 105

= 23

唯一性:在 [0, 105) 内只有 x=23 同时满足三个方程,这是 CRT 的核心保证。

RSA-CRT 加速解密

标准 RSA 解密是一次 m = c^d mod n 的大模幂运算,n 是 2048 位。RSA-CRT 把它拆成两个 1024 位的小模幂,再用 CRT 拼回来。

复制代码
p=61  q=53  e=17  明文m=65

密钥生成
n = 61 × 53 = 3233
φ(n) = (61-1)(53-1) = 3120
公钥 e = 17(gcd(17,3120)=1 ) 
私钥 d = 17⁻¹ mod 3120 = 2753(扩展欧几里得)
加密:c = 65^17 mod 3233 = 2790

原始解密
m = c^d mod n
m =  2790^2753 mod 3233
 m = 65
 
CRT 加速解密
d_p = d mod(p-1) = 2753 mod 60 = 53
d_q = d mod(q-1) = 2753 mod 52 = 49
m_p = c^d_p mod p = 2790^53 mod 61 = 4
m_q = c^d_q mod q = 2790^49 mod 53 = 12
q⁻¹ mod p = 53⁻¹ mod 61 = 38
h = 38×(4-12) mod 61 = 1
m = 12 + 1×53 = 65

二、古典密码和基础密码学

1 base家族编码:

复制代码
base16 / base32 / base64 / base58 / base85 / base 100

简述:
● Base16编码是将二进制文件转换成由16个字符组成的文本。
● base32的编码表是由(A-Z、2-7)32个可见字符构成,"="符号用作后缀填充。
● base64的编码表是由(A-Z、a-z、0-9、+、/)64个可见字符构成,"="符号用作后缀填充。
● base58的编码表相比base64少了数字0,大写字母I,O,小写字母 l (这个是L),以及符号'+'和'/'。
● base91的密文由91个字符(0-9,a-z,A-Z,!#$%&()*+,./:;<=>?@[]^_`{|}~")组成。
● Base100编码/解码工具(又名:Emoji表情符号编码/解码),可将文本内容编码为Emoji表情符号;同时也可以将编码后的Emoji表情符号内容解码为文本。

举例:

复制代码
base32: NBSWY3DPFR3W64TMMQXDCMRTGQ3DK===    
特征:大写字母(A-Z)和数字(2-7),不满5的倍数,用'='补齐。 
base64: aGVsbG8sd29ybGQuMTIzNDY1    
特征:大小写字母(A-Z,a-z)和数字(0-9)以及特殊字符'+','/',不满3的倍数,用'='补齐。
base58: 2smDFYXWKE8vc8XA8dadEYcSqcQb    
特征:相比Base64,Base58不使用数字"0",字母大写"O",字母大写"I",和字母小写"l",以及"+"和"/"符号,最主要的是后面不会出现'='。  
base85: BOu!rDst>tGAhM<A1fSl1GgsI   
特征:特点是奇怪的字符比较多,但是很难出现等号。 
base91: TPwJh>go2Tv!_,aRA2IbLmA   
特征:由91个字符(0-9,a-z,A-Z,!#$%&()*+,./:;<=>?@[]^_`{|}~")组成    不支持中文。 
base100: 👟👜👣👣👦📦💳💃👮👦👩👣👛🐥🐨🐩🐪🐫🐬🐭
特征:就是一堆Emoji表情  

Base64编码是从二进制到字符的过程,可用于在HTTP环境下传递较长的标识信息。采用Base64编码具有不可读性,需要解码后才能阅读。

Base64要求把每三个8Bit的字节转换为四个6Bit的字节(38 = 46 = 24),然后把6Bit再添两位高位0,组成四个8Bit的字节,也就是说,转换后的字符串理论上将要比原来的长1/3。

复制代码
例如:ABC
ASCII:
字符	ASCII	二进制
A	      65	  01000001
B	      66	  01000010
C	      67	  01000011
合并:
 01000001 01000010 01000011  
共 24 bit
每6位一组
 010000 010100 001001 000011  
得到  4组 × 6bit  
 6bit 最大值:2的6次方=64
所以需要64个字符

值	    字符
0--25	A--Z
26--51	a--z
52--61	0--9
62	+
63	/
 编码结果:   ABC → QUJD

2 rabbit密码

Rabbit 是流密码,它不直接加密数据块,而是生成一条伪随机"密钥流",再与明文逐位 XOR 得到密文。解密时用同样的密钥流再 XOR 一次,就能还原明文------这正是流密码天然对称的特点。

由字母、数字和 +/= 构成,无规律可循

复制代码
密文:U2FsdGVkX1/ATQxwhmM3vC9wXWeQlWDMPFMhGHE+eNE8a1r0AUKbUkjpbfHT3Td/
iD4Wl8wirAgGtw==
密钥:key
解密后 flag{3becfe0b-8b41-54e4-2b21-5d0d95b22845}

3 栅栏密码

栅栏密码是一种简单的移动字符位置的加密方法,规则简单,容易破解。栅栏密码的加密方式:把文本按照一定的字数分成多个组,取每组第一个字连起来得到密文1,再取每组第二个字连起来得到密文2......最后把密文1、密文2......连成整段密文.

举例:

复制代码
helloworld  栏数:2
hloolelwrd

4 凯撒密码

通过把字母移动一定的位数来实现加密和解密。明文中的所有字母都在字母表上向后(或向前)按照一个固定数目进行偏移后被替换成密文。

例如,当偏移量是3的时候,所有的字母A将被替换成D,B变成E,以此类推X将变成A,Y变成B,Z变成C。由此可见,位数就是凯撒密码加密和解密的密钥

5 对称加密

AES算法原理

AES(Advanced Encryption Standard,高级加密标准)是一种对称加密算法,意思是加密和解密用的是同一把密钥。它是目前最广泛使用的加密标准,安全、高效。

比如你有一个保险柜,用钥匙锁上(加密),用同一把钥匙打开(解密)

核心概念:三个关键参数

● 明文:你要加密的原始数据

● 密钥:加密/解密用的"钥匙",长度可以是 128/192/256 位

● 密文:加密后的数据

加密过程

AES 以 16字节(128位)为一个"块" 来处理数据,这个块叫做State(状态矩阵)。

AES-128 会进行 10轮迭代,每轮包含四个操作:

四个核心操作详解

  1. SubBytes(字节替换)
    每个字节通过查一张叫 S-Box 的固定替换表,换成另一个字节。这一步提供"混淆"效果,破坏字节之间的线性关系。
  2. ShiftRows(行移位)
    矩阵的每一行向左循环移位:
    ● 第0行:不动
    ● 第1行:左移1字节
    ● 第2行:左移2字节
    ● 第3行:左移3字节
    这一步让数据在矩阵的不同列之间"扩散"。
  3. MixColumns(列混淆)
    每一列的4个字节与一个固定矩阵在有限域(GF(2⁸))中做乘法运算。这一步让一个字节的变化影响整列,提供最强的"扩散"效果。最终轮跳过这一步。
  4. AddRoundKey(轮密钥加)
    State 矩阵与该轮的子密钥做按位 XOR。子密钥由初始密钥通过**密钥扩展算法(Key Expansion)**生成,AES-128 会生成 11 个子密钥(初始1个 + 每轮1个)。

解密过程

解密就是把加密每一步反过来做:

复制代码
加密步骤	   解密步骤
SubBytes	InvSubBytes(逆S-Box查表)
ShiftRows	InvShiftRows(循环右移)
MixColumns	InvMixColumns(逆矩阵乘法)
AddRoundKey	AddRoundKey(XOR自身可逆)

轮次顺序也是反过来执行的。

例题:

密文: 7a2f1b3c8e4d9f0a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4

key: MySuperSecretKey

python 复制代码
from Crypto.Cipher import AES

key = b'MySuperSecretKey'
ciphertext = bytes.fromhex(
    '7a2f1b3c8e4d9f0a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4'
)

cipher = AES.new(key, AES.MODE_ECB)
plaintext = cipher.decrypt(ciphertext)

# 去除 PKCS#7 填充
pad_len = plaintext[-1]
flag = plaintext[:-pad_len]
print(flag.decode())  # flag{AES_ECB_1s_W3ak!}

6 非对称加密

RSA是目前最有影响力和最常用的公钥加密算法,它能够抵抗到目前为止已知的绝大多数密码攻击,已被ISO推荐为公钥数据加密标准。

RSA算法原理:

算法基础 - 数论知识

● 互质关系:如果两个正整数,除了 1 以外,没有其他公因数,那么这两个数是互质关系。例如,15 和 8 是互质的,因为 15 的因数是 1、3、5、15,8 的因数是 1、2、4、8,它们只有公因数 1。

● 欧拉函数:对于正整数n,欧拉函数φ(n)表示小于等于n且与n互质的正整数的个数。例如,当n = 6 时,与 6 互质的数有 1 和 5,所以φ(6) = 2。

● 如果n是质数p,那么φ§ = p -1,因为所有小于p的正整数都与p互质。

● 模运算:模运算即求余数的运算。例如,7 mod 3 = 1,表示 7 除以 3 的余数是 1。在 RSA 算法中,模运算起到了关键作用,许多运算都是在模某个数的环境下进行的。

● 费马小定理和欧拉定理

○ 费马小定理:假如p是质数,且a与p互质,那么a^p-1 mod p = 1。例如,当p = 5,a = 3时,3^4 mod 5 = 81 mod 5 = 1。

■ 欧拉定理:若a与n互质,则a^φ(n) mod n = 1。它是费马小定理的推广,当n为质数时, φ(n) = n - 1,就退化成费马小定理。

密钥生成过程

● 步骤一:选择两个大质数p和q

○ 这两个质数要足够大,例如可以选择p = 61,q = 53。大质数的选择是为了增加破解的难度,因为分解两个大质数的乘积是非常困难的计算问题。

● 步骤二:计算n = p × q和φ(n)

复制代码
φ(n) = φ(p) × φ(q) = (p - 1) × (q - 1)
对于前面所选的p = 61和q = 53,n = 61 × 53 = 3233,φ(n) = (61 - 1) × (53 - 1) = 60 × 52 = 3120。

步骤三:选择一个整数e,使得1 < e < φ (n)且e与 φ(n)互质

复制代码
通常选择一个较小的质数作为e,比如e = 17,因为17与3120互质,满足条件。这个e就是公钥的一部分。

步骤四:计算d,使得e × d mod φ(n),即d是e在模 φ(n)下的乘法逆元

复制代码
可以使用扩展欧几里得算法来计算d。对于e = 17和φ(n) = 3120,通过计算得到d = 2753。这个就是私钥的一部分。

最终密钥:公钥是(e,n),即(17,3233);私钥是(d,n),即(2753,3233)。

加密过程

● 假设要加密的消息是m(必须是小于n的整数),例如m = 123。使用公钥(e,n)进行加密,加密公式为c = m^e mod n。

● 对于e = 17,n = 3233,m = 123,计算c = 123^17 mod 3233。通过计算得到c = 855,这就是加密后的密文。

解密过程

● 使用私钥(d,n)对密文c进行解密,解密公式为m = c^d mod n。

● 对于前面得到的c = 855,d = 2753,n = 3233,计算m = 855^2753 mod 3233,经过计算可以得到m = 123,即还原出了原始消息。

例题:

复制代码
p = 9648423029010515676590551740010426534945737639235739800643989352039852507298491399561035009163427050370107570733633350911691280297777160200625281665378483
q = 11874843837980297032092405848653656852760910154543380907650040190704283358909208578251063047732443992230647903887510065547947313543299303261986053486569407
e = 65537
c = 83208298995174604174773590298203639360540024871256126892889661345742403314929861939100492666605647316646576486526217457006376842280869728581726746401583705899941768214138742259689334840735633553053887641847651173776251820293087212885670180367406807406765923638973161375817392737747832762751690104423869019034

已知p、q、e、c 求m:解题流程如下:

  1. 计算φ(n)=(p-1)(q-1)
  2. 求d ≡ e⁻¹ mod φ(n)
  3. 解密m ≡ cᵈ mod n
python 复制代码
from Crypto.Util.number import long_to_bytes
 
p = 9648423029010515676590551740010426534945737639235739800643989352039852507298491399561035009163427050370107570733633350911691280297777160200625281665378483
q = 11874843837980297032092405848653656852760910154543380907650040190704283358909208578251063047732443992230647903887510065547947313543299303261986053486569407
e = 65537
c = 83208298995174604174773590298203639360540024871256126892889661345742403314929861939100492666605647316646576486526217457006376842280869728581726746401583705899941768214138742259689334840735633553053887641847651173776251820293087212885670180367406807406765923638973161375817392737747832762751690104423869019034
 
phi = (p-1)*(q-1)
d = pow(e, -1, phi)
m = pow(c, d, p*q)
print(long_to_bytes(m))
离散对数与 Diffie-Hellman (DH)

离散对数问题是许多加密协议(如 DH 密钥交换)的基础。它利用了幂运算在模运算下的"混乱"特性。

正向计算简单,逆向求解极难

想象一个公式:g^a mod p = A。其中g、p是公开的大素数,a是 Alice 自己选的秘密数。已知g、p、a 求公开值A(公钥)很容易(指数运算后取模)。但攻击者即使截获了公开的g、p、A,想反过来求出秘密数a,在现有计算能力下几乎不可能,这就是离散对数难题。

DH协议的安全就基于此:秘密(a, b)不传输,只交换公开计算结果(A, B),最终双方能独立算出相同的共享密钥 K = B^a mod p = A^b mod p,而旁观者无法算出K。

DH密钥交换就像两个人在公开场合通过"颜色混合"的比喻约定一个秘密颜色。其标准化操作分为四步:

复制代码
1 协商公开参数:双方选定一个大素数 p 和一个生成元 g。这两个数公开传输,毫无保密必要。
2 生成各自密钥对:Alice随机选私钥 a,计算公钥 A = g^a mod p;Bob随机选私钥 b,计算公钥 B = g^b mod p。私钥a/b必须绝对保密。
3 交换公钥:Alice将A发送给Bob,Bob将B发送给Alice。这个过程可以被任何人监听。
4 计算共享密钥:Alice收到B后,用自己私钥a计算 K = B^a mod p;Bob收到A后,用自己私钥b计算 K = A^b mod p。根据模幂运算定律,双方计算出的K是相同的,即 g^(a*b) mod p。

核心要点:整个过程中,网络上只流动了 p, g, A, B 四个公开数,秘密的 a, b, K 从未出现。攻击者由公开信息推不出K。

椭圆曲线密码学 (ECC)

ECC 是目前主流的加密标准(如比特币、TLS 1.3)。它基于椭圆曲线离散对数问题 (ECDLP)。

核心原理

椭圆曲线通常表示为方程:y2=x3+ax+by^2 = x^3 + ax + by2=x3+ax+b。

在 ECC 中,我们不处理连续的曲线,而是处理有限域上的离散点。

1 点运算:在曲线上定义一种特殊的"加法"。给定点 P,计算 2P, 3P,...相当于在曲线上进行多次跳跃。

2 标量乘法:计算 Q = kP。

k 的特征它必须足够大:在 256 位加密中,kkk 的取值范围接近 22562^{256}2256(约等于宇宙中原子的数量)。如果 kkk 太小,别人很快就能暴力破解。

复制代码
给定 k 和 P,计算 Q 很快。但给定 Q 和 P,想要反推 k 极其困难。

ECC在相同的安全强度下,ECC 所需的密钥长度远短于 RSA。256 位的 ECC 密钥安全性大致相当于 3072 位的 RSA 密钥。由于密钥短,计算量小,内存占用少,非常适合移动设备和物联网终端。

三、密码协议

密钥交换协议

在公开的互联网上,两个从未谋面的主体如何协商出一个只有他们知道的秘密?

1 Diffie-Hellman (DH):最经典的协议。双方交换公钥,结合各自的私钥,计算出相同的共享密钥。

2 完美前向安全性 (PFS):现代协议(如 TLS 1.3)强调 PFS。这意味着即使服务器的长期私钥在未来某天泄露,攻击者也无法解密过去已经结束的通信会话,因为每次会话的密钥都是临时生成的。

认证协议

认证协议用于确认"你确实是你所声称的那个人"。

挑战-响应机制:

复制代码
1 服务器发送一个随机数。
2 用户用自己的私钥对该随机数签名并传回。
3 服务器用用户的公钥验签,成功则证明用户持有正确的私钥。
4 数字证书与 PKI:为了防止"中间人攻击",我们需要一个可信的第三方(CA)。CA 给用户的公钥签名。

零知识证明

它允许证明者在不向验证者透露任何有用信息的前提下,使验证者相信某个命题是正确的。

核心属性

复制代码
完备性:如果是真的,证明者能说服验证者。
可靠性:如果是假的,证明者几乎不可能骗过验证者。
零知识性:验证者除了知道命题是真的以外,得不到任何其他信息。

在隐私币,区块链方面应用较多

安全多方计算

解决的是"协同计算但互不信任"的问题。它允许一组参与者共同计算一个函数的结果,同时保证各自的输入数据对他人不可见。

比如:两个富翁想知道谁更有钱,但谁都不想告诉对方自己到底有多少钱。

核心技术

1 秘密共享 (Secret Sharing):将数据拆成碎片,分给不同的人,只有凑齐足够多的碎片才能还原数据。

2 混淆电路 (Garbled Circuits):将计算逻辑加密,让参与者在看不见具体数值的情况下执行逻辑运算。

应用场景:隐私保护下的数据挖掘、多机构联合风控、分布式密钥管理。

相关推荐
橘子编程1 天前
密码学完全指南:从基础到实战
java·python·密码学
lcreek1 天前
公钥密码学与数字签名:原理详解
密码学
洒家肉山大魔王5 天前
PKI/CA X.509证书的基础应用与解读
服务器·https·密码学·数字证书
酿情师6 天前
2026软件系统安全赛初赛RSA(赛后复盘)
android·网络·安全·密码学·rsa
Liudef067 天前
后量子密码学(PQC)深度解析:算法原理、标准进展与软件开发行业的影响
算法·密码学·量子计算
YIN_尹9 天前
关于论文《使用 FLUSH+RELOAD 缓存侧信道攻击恢复 OpenSSL ECDSA 的随机数》的理解
缓存·系统安全·密码学
MicroTech202514 天前
基于后量子密码学:微算法科技(NASDAQ: MLGO)区块链预言机加密可更新方案
科技·区块链·密码学
道法自然|~15 天前
BugCTF黄道十二宫
算法·密码学
温中志16 天前
计算机密码学基础
密码学