RSA(解题方法汇总一)

RSA简述

1、选择两个大的参数,计算出模数 N = p * q
2、计算欧拉函数 φ = (p-1) * (q-1),然后选择一个e(1<e<φ),并且e和φ互质(互质:公约数只有1的两个整数)
3、取e的模反数d,计算方法为:e * d ≡ 1 (mod φ) (模反元素:如果两个正整数e和n互质,那么一定可以找到整数d,使得 e * d - 1 被n整除,或者说e * d被n除的余数是1。这时,d就叫做e的“模反元素”。欧拉定理可以用来证明模反元素必然存在。两个整数a,b,它们除以整数M所得的余数相等:a ≡ b(mod m),比如说5除3余数为2,11除3余数也为2,于是可写成11 ≡ 5(mod 3)。)
4、对明文m进行加密:c = pow(m, e, N),可以得到密文c。
5、对密文c进行解密:m = pow(c, d, N),可以得到明文m。

整理:

p 和 q:两个大的质数,是另一个参数N的的两个因子。
N:大整数,可以称之为模数
e 和 d:互为无反数的两个指数
c 和 m:密文和明文
(N, e):公钥
(N, d):私钥
pow(x, y, z):效果等效pow(x, y)1 % z, 先计算x的y次方,如果存在另一个参数z,需要再对结果进行取模。
密钥长度:n以二进制表示的的位数,例如密钥长度为512代表n用二进制表示的长度为512bit。

RSA安全性分析

对于RSA加密算法,公钥(N, e)为公钥,可以任意公开,破解RSA最直接(亦或是暴力)的方法就是分解整数N,然后计算欧拉函数φ(n)=(p-1) * (q-1),再通过d * e ≡ 1 mod φ(N),即可计算出 d,然后就可以使用私钥(N, d)通过m = pow(c,d,N)解密明文。

保障RSA的安全性

1.定期更换密钥
2.不同的用户不可以使用相同的模数N
3.p与q的差值要大,最好是差几个比特
4.p-1与q-1都应该有大的素因子,一般建议选择的两个大素数p、q使得p=2p+1和q=2q+1也是素数
5.e的选择不要太小
6.d的选择也是不可以太小,最好满足d>=n的4分之1

常用的攻击方法

直接分解模数N

直接分解模数N是最直接的攻击方法,也是最困难的方法。具体的解析同上RSA安全性分析。
如果n小于256bit,可以使用本地工具进行暴力分解,例如windwods平台的RSATool,可以在数分钟之内完成256bit的n的分解。
如果n大于768bit,可以尝试利用在线网站http://factordb.com, 这一类在线网站的原理是储存了部分n分解成功的的值。

CTF原题

题目链接:http://ctf5.shiyanbar.com/crypto/RSAROLL.txt

{920139713,19}
 
704796792
752211152
274704164
18414022
368270835
483295235
263072905
459788476
483295235
459788476
663551792
475206804
459788476
428313374
475206804
459788476
425392137
704796792
458265677
341524652
483295235
534149509
425392137
428313374
425392137
341524652
458265677
263072905
483295235
828509797
341524652
425392137
475206804
428313374
483295235
475206804
459788476
306220148

分解N可以通过在线网站http://www.factordb.com/index.php
分解920139713可以得到p和q的值为18443和49891,现在已知p、q、e以及c,可以通过前三个参数求出d
安装gmpy2可以参考https://blog.csdn.net/wanzt123/article/details/71036184

import gmpy2
p = gmpy2.mpz(18443)#初始化大整数
q = gmpy2.mpz(49891)
e = gmpy2.mpz(19)
phi_n = (p-1)*(q-1)
d = gmpy2.invert(e,phi_n)#invert(x,m)返回y使得x * y == 1 modulo m,如果不存在y,则返回0
print("p=%s,q=%s,e=%s"%(p,q,e))
print("d is:\n%s"%d)
p=18443,q=49891,e=19
d is:
96849619

到目前为止,已经求出p,q,e,d,n,c,然后可以求出相应的明文M,

#求明文
import gmpy2
n = 920139713
d = 96849619
c = """
704796792
752211152
274704164
18414022
368270835
483295235
263072905
459788476
483295235
459788476
663551792
475206804
459788476
428313374
475206804
459788476
425392137
704796792
458265677
341524652
483295235
534149509
425392137
428313374
425392137
341524652
458265677
263072905
483295235
828509797
341524652
425392137
475206804
428313374
483295235
475206804
459788476
306220148
"""
result = ""
c_list = c.split()
#print(c_list)
for i in c_list:
    result += chr(pow(int(i),d,n))
print(result)

对RSA的公共模数攻击

适用于:使用相同的模数 N 、不同的私钥,加密同一明文消息

基本原理

假如采用两个或者两个以上的公钥(N,e)来加密同一条信息,可以得到下面的结论:

c1 = pow(m, e1, N)
c2 = pow(m, e2, N)

分别拿对应的私钥来加密,可以得到相同的明文m

m = pow(c1, d1, N)
m = pow(c2, d2, N)

假设攻击者已知n,e1,e2,c1,c2,即可可以得到明文m,因为e1和e2互质,所以使用欧几里得算法(用于计算两个整数a,b的最大公约数)可以找到能够满足以下条件的x,y:

pow(x,e1)+pow(y,e2)=1

假设x为负数,需再使用欧几里得算法来计算

pow(c1,-1)

则可以得到

pow(pow(c1,-1),-x) * pow(c2,y) = p mod(n)

如果p<n,则p可以被计算出来。
地址:https://www.ichunqiu.com/battalion?q=2451

# coding=utf-8
import gmpy2

def ByteToHex(bins):
    return ''.join(["%02X" % x for x in bins]).strip()

def n2s(num):
    t = hex(num)[2:]
    if len(t) % 2 == 1:
        t = '0' + t
    return ''.join([chr(int(b, 16)) for b in [t[i:i + 2] for i in range(0, len(t), 2)]])

n = 0x00b0bee5e3e9e5a7e8d00b493355c618fc8c7d7d03b82e409951c182f398dee3104580e7ba70d383ae5311475656e8a964d380cb157f48c951adfa65db0b122ca40e42fa709189b719a4f0d746e2f6069baf11cebd650f14b93c977352fd13b1eea6d6e1da775502abff89d3a8b3615fd0db49b88a976bc20568489284e181f6f11e270891c8ef80017bad238e363039a458470f1749101bc29949d3a4f4038d463938851579c7525a69984f15b5667f34209b70eb261136947fa123e549dfff00601883afd936fe411e006e4e93d1a00b0fea541bbfc8c5186cb6220503a94b2413110d640c77ea54ba3220fc8f4cc6ce77151e29b3e06578c478bd1bebe04589ef9a197f6f806db8b3ecd826cad24f5324ccdec6e8fead2c2150068602c8dcdc59402ccac9424b790048ccdd9327068095efa010b7f196c74ba8c37b128f9e1411751633f78b7b9e56f71f77a1b4daad3fc54b5e7ef935d9a72fb176759765522b4bbc02e314d5c06b64d5054b7b096c601236e6ccf45b5e611c805d335dbab0c35d226cc208d8ce4736ba39a0354426fae006c7fe52d5267dcfb9c3884f51fddfdf4a9794bcfe0e1557113749e6c8ef421dba263aff68739ce00ed80fd0022ef92d3488f76deb62bdef7bea6026f22a1d25aa2a92d124414a8021fe0c174b9803e6bb5fad75e186a946a17280770f1243f4387446ccceb2222a965cc30b3929
e1 = 17
e2 = 65537
# gmpy2.gcdext(e1,e2)的运行结果为元组(mpz(1), mpz(30841), mpz(-8)),所以元组的第0个值不能取,第1个值才是s1,第2个值由于是负数,所以要取反,变为正数
# gcdext(a,b)返回一个3元素元组(g,s,t)
# g == gcd(a,b)最大公约数和g == a * s + b * t
s = gmpy2.gcdext(e1, e2)
s1 = s[1]
s2 = -s[2]
file1 = open("veryhardRSA/flag.enc1", 'rb').read()  # 这里的路径要自己修改
c1 = int(ByteToHex(file1), 16)
file2 = open("veryhardRSA/flag.enc2", 'rb').read()  # 这里的路径要自己修改
c2 = int(ByteToHex(file2), 16)
# 由于根据前面的运算,s1是正数,s2是负数,后面需要运算c2的s2次幂。因为在数论模运算中,要求一个数的负数次幂,与常规方法并不一样,比如此处要求c2的s2次幂,就要先计算c2的模反元素c2r,然后求c2r的-s2次幂。
c2 = gmpy2.invert(c2, n)
m = (pow(c1, s1, n) * pow(c2, s2, n)) % n
print(n2s(m))

RSA小指数e攻击
如果RSA系统的公钥e选取较小的值,可以使得加密和验证签名的速度有所提高,但是如果e的选取太小,就容易受到攻击。

有三个分别使用不同的模数n1,n2,n3,但是都选取e=3,加密同一个明文可以得到:

c1 = pow(m,3,n1)
c2 = pow(m,3,n2)
c3 = pow(m,3,n3)

一般情况下,n1,n2,n3互素,否则会比较容易求出公因子,从而安全性大幅度的减低。

RSA选择密文攻击
在此种攻击模型中,攻击者需要掌握的内容包括:加密算法、截获的部分密文、自己选择的密文消息以及相应的被解密的明文。

利用公约数
思路
如果两次加密的n1和n2具有相同的素因子,可以利用欧几里德算法直接分解n1和n2.
通过欧几里德算法计算出两个n的最大公约数p:

def gcd(a, b):
    if a < b:
        a, b = b, a
    while b != 0:
        temp = a % b
        a = b
        b = temp
def gcd_digui(a, b):
    if b != 0:
        return a
    return gcd(b,a%b)

p = gcd(n1,n2)

识别
识别此类题目,通常会发现题目给了若干个n,均不相同,并且都是2048bit,4096bit级别,无法正面硬杠,并且明文都没什么联系,e也一般取65537。
例题

n1=9051013965404084482870087864821455535159008696042953021965631089095795348830954383127323853272528967729311045179605407693592665683311660581204886571146327720288455874927281128121117323579691204792399913106627543274457036172455814805715668293705603675386878220947722186914112990452722174363713630297685159669328951520891938403452797650685849523658191947411429068829734053745180460758604283051344339641429819373112365211739216160420494167071996438506850526168389386850499796102003625404245645796271690310748804327
n2=13225948396179603816062046418717214792668512413625091569997524364243995991961018894150059207824093837420451375240550310050209398964506318518991620142575926623780411532257230701985821629425722030608722035570690474171259238153947095310303522831971664666067542649034461621725656234869005501293423975184701929729170077280251436216167293058560030089006140224375425679571181787206982712477261432579537981278055755344573767076951793312062480275004564657590263719816033564139497109942073701755011873153205366238585665743

直接分解成功。而欧几里得算法的时间复杂度为:O(log n)。这个时间复杂度即便是4096 bit也是秒破级别
根据欧几里德算法算出的p之后,再用n除以p即可求出q,由此可以得到的参数有p、q、n、e,再使用常规方法计算出d,即可破解密文。

Fermat方法与Pollard rho方法
针对大整数的分解有很多种算法,性能上各有优异。
在p,q的取值差异过大,或者p,q的取值过于相近的时候,Format方法与Pollard rho方法都可以很快将n分解成功。
此类分解方法有一个开源项目yafu将其自动化实现了,不论n的大小,只要p和q存在相差过大或者过近时,都可以通过yafu很快地分解成功。yafu也有linux版本,但是我这存在一些问题装不上,能解决这个问题的大佬可以私信。

识别
不能直接分解n,不能使用公约数分解n,可以尝试yafu。

低加密指数攻击
在RSA中的e被称为加密指数。由于e的选择只需要满足以下条件即可

计算欧拉函数 φ = (p-1) * (q-1),然后选择一个e(1<e<φ),并且e和φ互质

选择小的e可以缩短加密时间,但是选择的e不当,可能会造成严重的安全问题。
e=3的小明文攻击
当e=3,并且明文过小时,导致明文的三次方仍然小于n,通过直接对密文三次开方,即可得到明文。
原理如下

对明文m进行加密:c = pow(m, 3, N),可以得到密文c。
因为n > pow(m, 3),所以c = pow(m, 3, N) = pow(m, 3),故对密文三次开方,即可得到明文。

有一种特殊的情况是:pow(m, 3) > n,但是不是足够,假设存在这样的k,有下列的公式成立:

c = pow(m, 3) + k * n

爆破k,当且仅当c - (k * n)可以开三次方,c - (k * n)开三次方结果就是明文m。

识别
当e=3时,优先使用这种方法解密。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,997评论 6 502
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,603评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,359评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,309评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,346评论 6 390
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,258评论 1 300
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,122评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,970评论 0 275
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,403评论 1 313
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,596评论 3 334
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,769评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,464评论 5 344
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,075评论 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,705评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,848评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,831评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,678评论 2 354

推荐阅读更多精彩内容