RSA
作者:互联网
RSA公钥密码体制全梳理
算法原理
- 模 \(\mathrm{pq}\) 时高次同余方程的求解
假设 \(\mathrm{p}\) 和 \(\mathrm{q}\) 是不同的素数, 并假设 \(e \geq 1\), 满足
则 \(e\) 模 \((p-1)(q-1)\) 存在逆元, 即
\[d e \equiv 1(\bmod (p-1)(q-1)) \]则同余方程
\[x^{e} \equiv c(\bmod p q) \]有唯一解 \(x \equiv x^{ed} \equiv c^{d}(\bmod p q)\)
- 安全性分析
已知 \(p 、q\) 时该方程易解,敌手可以计算欧拉函数\(\varphi(n)=(p-1)(q-1)\),然后利用扩展欧几里得算法计算\(e\)对于\(\varphi(n)\)的乘法逆元\(d\),然后解密。
而\(\mathrm{p、q}\)未知时,已知公钥\((e,n)\)求私钥等价于大数因子分解问题;已知一对\((M,C)\)试图还原\(d\),等价于离散对数问题。
算法流程
- 密钥生成过程:
选择两个大素数 \(p 、 q\), 计算公开模数:
选择公开加密指数 e,满足:
\[\operatorname{gcd}(e,(p-1)(q-1))=1 \]- RSA 加密过程:
将明文转化为整数 \(\mathrm{m}\),使用公钥N计算
得到密文\(C\)
3. RSA解密过程:
已知\(p,q\),计算\(d\):
然后计算明文M:
\[M\equiv C^d(\bmod N) \]在实际应用中,RSA加解密经过分组的数据段,这些数据段长度相等,固定长度时长度不足的数据段需要进行填充。
算法实现
-
使用快速模幂运算计算,
python
中使用pow
函数可以达到同样的效果。 -
一般加密过程e比较小,可以快速实现,但解密时d比较大所以实际中利用中国剩余定理来加快计算:
-
密钥产生——伪随机数发生器、执行素数判定测试(Miller Rabin)
-
安全性优化——密钥生成阶段参数选择(否则会产生参数选取不当攻击)
(1)使用大素数,同时要求p,q相差很大
(2)尽量使用强素数p,q,强素数指p-1有很大的素因子。否则若p-1没有很大的质因数,而是由m个较小的质因数\(p_1p_2...p_m\)组成。则\(p-1=p_1^{a_1}p_2^{a_2}...p_m^{a_m}\),那么,要分解n则相对容易。(有相关论文可以找到详细分解方法)
(3)\(d>N^\frac{1}{4}\),避免连分式理论
对RSA的攻击方式
因式分解攻击
分解成功后按照算法原理中的内容可以计算得到明文m
- 分解方式
- 可以先查询网站http://factordb.com试试
参数选取不当攻击
p,q相差要大(但不能过大)
-
\(|p-q|\)小时,\(\frac{(p-q)^2}{4}\)也小,此时\(\frac{(p+q)^2}{4}\)稍大于\(n\),即\(\frac{(p+q)}{2}\)稍大于\(n^\frac{1}{2}\).
\[\frac{(p+q)^2}{4}-n=\frac{(p+q)^2}{4}-pq=\frac{(p-q)^2}{4} \]那么:
while \(x>n^\frac{1}{2}\):
if \(x^2-n=y^2\):
\(n=(x+y)(x-y)\)
d特别小,e很大(接近N)
-
问题描述
flag = s2n(flag) p = getPrime(1024) q = getPrime(1024) if p < q: p, q = q, p assert q < p < 2 * q phi = (p - 1) * (q - 1) N = p * q d = randint(0, int(iroot(N, 4)[0]) // 3) print(f'N = {N}') print(f'd = {d}') e = invmod(d, phi) print(f'e = {e}') c = pow(flag, e, N) print(f'c = {c}') ''' N = 21327609432635697635661734492967514868032345219646509293473450728946796929125596264796686608077350282146808431543688814099354946988813695125850734043400446455515569653767982263228375866016212125033017742119349015072822178318196190745694850995570515630230752678292777440574778729120793338895028632923682027496271327472935942662500117169921554840041050071839641224638348524022215169727418319630285293394980617769914591506983043636592739835090149763802884920200300368993239366686843677366099965654860267609759882686378049533310393901183559714507043035045332273502601434654726043496991435324318063462466253726816633686491 e = 18977835107309220930390004484766560831346929608900345454868912576417879395319152391809677007908654095951324946088077940809180932163517507338773363819836058226479707254933679974004335002153790380237807333376658330135322627930737835299410373663744954613372507542594748704398503555416693543828015836373800739443278657909905379530092958500438988035068330839162959013568315176411267327500693507377318806169025417092598473813234048525222602269176512302545380940501266666455315603787471273429334914051803354595877792553046681362881913923273953799258321308753602286651515092850863999625965095880385885087205694014033060741113 c = 2951989543787250024227309988919939594167825226148750874062428524625014545445228307222640088545937734380203828988989321941362142365155595290586130523703955533644047842799047518117049515659231726842039527270329713890518786418601487875975864228006745361862477308867519292913016550436143764016127132235503694918940332463597026396960672403183254520332051492462851679089378927071373658225211987354898477962818171916800202243021649078952845125153161320695143579666246174891848723194556125740925439954503389599981696506010841328091656707182777225501527571416356759631836676820899342968642257694841513191347688952532566252238 '''
-
攻击原理
在数学中,连分数或繁分数即如下表达式
由于 \(e d \equiv 1(\bmod \varphi(N))\) ,所以存在整数 \(\mathrm{k}\) ,满足
\[e d-k \varphi(N)=1 \]由于 \(N=p q>q^{2}\), 即 \(q<N\) ,所以
\[\begin{gathered} 0<N-\varphi(N)=p+q-1<2 q+q-1<3 q<3 \sqrt{N} \\ \Rightarrow\left|\frac{e}{N}-\frac{k}{d}\right|=\left|\frac{e d-k N}{d N}\right|=\left|\frac{1+k(\varphi(N)-N)}{d N}\right|<\frac{3 k \sqrt{N}}{d N}=\frac{3 k}{d \sqrt{N}} \end{gathered} \]由于 \(k<d\), 所以 \(3k<3d<N^{\frac{1}{4}}\), 即
\[\left|\frac{e}{N}-\frac{k}{d}\right|<\frac{1}{d N^{\frac{1}{4}}} \quad \Rightarrow \quad \left|\frac{e}{N}-\frac{k}{d}\right|<\frac{1}{3 d^{2}} \]由连分数理论,此时 \(\frac{k}{d}\) 是 \(\frac{e}{N}\) 的一个收敛子:
计算 \(\frac{e}{N}\) 的连分数展开, 依次算出每一个渐进分数。因为 \(\frac{e}{N}>\frac{k}{d}\),所以 \(\frac{e}{N}\) 的渐进分数覆盖了 \(\frac{k}{d^{\circ}}\) 。 就是说 \(\frac{e}{N}\) 的渐进分数里有等于 \(\frac{k}{d}\) 的分数。接着验证 \(k, d\) 是否满足条件就求得了 \(k, d\) 的值
-
攻击代码
# numerator(n):分子, denominator(d):分母 def t_cf(n, d): # 将分数 x/y 转为连分数的形式 res = [] while d: res.append(n // d) n, d = d, n % d return res def cf(sub_res): # 得到渐进分数的分母和分子 n, d = 1, 0 for i in sub_res[::-1]: # 从后面往前循环 d, n = n, i * n + d return d, n def list_fraction(x, y): # 列出每个渐进分数 res = t_cf(x, y) res = list(map(cf, (res[0:i] for i in range(1, len(res))))) # 将连分数的结果逐一截取以求渐进分数 return res def get_pq(a, b, c): # 由p+q和pq的值通过维达定理来求解p和q(解二元一次方程) par = gmpy2.isqrt(b * b - 4 * a * c) # 由上述可得,开根号一定是整数,因为有解 x1, x2 = (-b + par) // (2 * a), (-b - par) // (2 * a) return x1, x2 def wienerAttack(e, n): for (d, k) in list_fraction(e, n): # 用一个for循环来注意试探e/n的连续函数的渐进分数,直到找到一个满足条件的渐进分数 if k == 0: # 可能会出现连分数的第一个为0的情况,排除 continue if (e * d - 1) % k != 0: # ed=1 (mod φ(n)) 因此如果找到了d的话,(ed-1)会整除φ(n),也就是存在k使得(e*d-1)//k=φ(n) continue phi = (e * d - 1) // k # 这个结果就是 φ(n) px, qy = get_pq(1, n - phi + 1, n) if px * qy == n: p, q = abs(int(px)), abs(int(qy)) # 可能会得到两个负数,负负得正未尝不会出现 d = gmpy2.invert(e, (p - 1) * (q - 1)) # 求ed=1 (mod φ(n))的结果,也就是e关于 φ(n)的乘法逆元d return d print("求解d失败") d = wienerAttack(e,N) #print(d) m=int(pow(c,d,N)) flag = n2s(m) print(flag)
选择密文攻击/中间人攻击
- RSA算法具有同态特点,即对任意\(x_1,x_2\in Z_n\),有\(E_k(x_1,x_2)=E_k(x_1)E_k(x_2)\).
攻击人截获密文\(c\),发出伪造密文\(r^ec\)(\(r\)为随机数),可以获得对应明文\(m^`=(r^ec)^d=r^{ed}c^d=rm(\bmod N)\),得
- RSA-OAEP可抗击适应性选择密文攻击(EUROCRYPT'94,Bellare-Rogaway, Optimal Asymmetric Encryption Padding (OAEP))
RSA最优非对称加密填充 (RSA-OAEP) 的密钥参数 \(\left(N, e, d, G, H, n, k_{0}, k_{1}\right)\) 满足:-
\((N, e, d)\) 是RSA的密钥, 其中
\(d=e^{-1}(\bmod \varphi(N))\), 并且 \(\mid N f=k=n+k_{0}+k_{1}, \mathrm{n}\) 是明文消息的长度, -
\(\mathrm{G}, \mathrm{H}\)是两个杂湊函数, 且满足\(G:\{0,1\}^{k_{0}} \rightarrow\{0,1\}^{k-k_{0}}, H:\{0,1\}^{k-k_{0}} \rightarrow\{0,1\}^{k_{0}}\)
-
设 \((N, e)\) 是Alice的RSA公钥, \(d\) 是私钥。
加密过程:
为了发送一个消息 \(m \in\{0,1\}^{n}\), 给Alice, Bob执行以下几步计算:- \(r \leftarrow_{U}\{0,1\}^{k_{0}} ; s \leftarrow\left(m \| 0^{k_{1}}\right) \bigoplus G(\hat{r}) ; t=r \bigoplus H(s)\)
- 如果 \((s \| t \geq N)\), 则返回 \(V_{a}\)
\(c \leftarrow(s \| t)^{e}(\bmod N)\) - 所得密文为 \(c\)
解密过程:
收到密文 \(c\) 后, Alice执行以下几步计算:- \(s|| t \leftarrow c^{d}(\bmod N)\) 满足 \(|s|=n+k_{1} \underset{k}{1}-k_{0},|t|=k_{0}\)
- \(u \leftarrow t \bigoplus H(s) ; v=s \bigoplus G(u)\)
- 输出 \(\left\{\begin{array}{c}m, \text { 若 } v=m \| 0^{k_{1}} \\ \text { 拒绝, 其他 }\end{array}\right.\)
-
共模攻击
对于给定的模数N,最多应该只使用一个加密指数,不同用户间不要共享N
- 攻击原理
用公开指数\(e_1,e_2\)加密同一段明文\(m\),且公开模数\(N\)不变.
若截获密文
\(c_1≡m^e_1 (mod N)\)和 \(c_2≡m^e_2 (mod N)\)
可解出\(u、v\): \(e_1u+e_2v=gcd(e_1,e_2)\)
进而 \(c_1^uc_2^v≡m^e1um^e2v≡m^{gcd(e1,e2)} (mod N)\)
若解得\(gcd(e_1,e_2)=1\),可直接得到\(m\)
低指数广播攻击
同一份明文使用不同模数和相同指数多次加密,可以考虑用中国剩余定理破解,然后直接开e次
\[\begin{gather*} c_1=m^e (mod ~~n_1)\\ c_2=m^e (mod n_2)\\ \dots\\ c_n=m^e (mod n_n)\\ \Rightarrow m^e≡x(mod~~ n_1…n_n) \end{gather*} \]e很小时可以直接爆破
循环攻击
在构造n时应选择
标签:right,frac,bmod,RSA,equiv,left 来源: https://www.cnblogs.com/skye-rs/p/16199085.html