RSA加密算法
rsa基本组成
在RSA加密算法中,以下是常用的符号和对应的含义:
e:公钥指数(exponent),用于加密操作。通常为一个较小的固定值,例如65537。
p和q:两个不同的大素数,用于生成RSA密钥对。它们的乘积n (n = p * q) 是模数(modulus),用于加密和解密操作。
d:私钥指数(exponent),用于解密操作。它通过使用扩展欧几里得算法计算得到,满足 e * d ≡ 1 (mod φ(n)),其中 φ(n) 是欧拉函数值。
n:模数(modulus),也是公钥和私钥共享的一个参数。它是两个素数 p 和 q 的乘积,即 n = p * q。
φ(n)即phi:欧拉函数(Euler’s totient function)的值,表示与 n 互质的正整数的数量。对于两个素数 p 和 q 的乘积 n,φ(n) = (p-1)*(q-1)。
m:明文(plaintext),需要被加密的消息或数据。m=c^d mod n
c: 密文,c=m^e mod n
总结:
e是公钥指数,p和q是素数,d是私钥指数,n是模数,phi是欧拉函数值,m是明文。
已知p,q,e求d(rsa)
我们导入python的gmpy2库,这个库求rsa超好用
1 | from gmpy2 import invert |
成功得到flag
已知p,q,e,c 求明文m [buu rsarsa题]
1 | from libnum import n2s,s2n |
已知p,q,dp,dq,c 求明文m [buu RSA1题]
小记一下:在RSA密码中,dp和dq是私钥的参数,用于加速中国剩余定理(Chinese Remainder Theorem, CRT)解密算法。
dp:是d对p-1的模反元素(modular inverse)。即 dp = d mod (p-1)。
dq:是d对q-1的模反元素。即 dq = d mod (q-1)。
这两个参数在CRT解密算法中起到加速解密过程的作用,通过使用CRT算法可以减少模幂运算的计算量,提高解密效率。具体来说,当进行解密时,先对密文进行两次模幂运算,分别使用dp和dq,并分别取得结果m1和m2。然后根据CRT算法,使用p、q、dp、dq以及模数n计算出明文m。这种方式相比于直接使用d进行模幂运算,能够大大提高解密速度。
m = (m1 + (I * (m2 - m1)) * p) % n
1 | from libnum import n2s,s2n |
逆元
给定整数 𝑎a 和模数 𝑚m,如果存在一个整数 𝑥x,使得:
𝑎⋅𝑥≡1(mod𝑚)a⋅x≡1(modm)
那么这个 𝑥x 就是 𝑎a 的模 𝑚m 下的乘法逆元,记作 𝑎−1(mod 𝑚)a−1(mod m)。
已知e1,e2,c1,c2,n 求明文m(共模攻击)[buu RSA3]
小记一下:
根据给定的参数 e1、e2、c1、c2 和模数 n,下面是求解明文 m 的一般步骤:
使用扩展欧几里得算法计算 e1 和 e2 的最大公约数 gcd(e1, e2)。确保它等于 1,否则无法进行共模攻击。
计算 e1 在模 e2 下的模反元素 s1 = e1^-1 mod e2,以及 e2 在模 e1 下的模反元素 s2 = e2^-1 mod e1。
计算明文 m:
计算 x = (c1^s1 * c2^s2) mod n。
计算 m = x mod n。
需要注意的是,在实际计算过程中,可以使用模幂运算算法和模反元素算法来进行计算。
此外,如果 m 不在 0 到 n-1 的范围内,还需要对结果进行适当的调整,以保证明文 m 在正确的范围内。
1 | from gmpy2 import * |
已知e,n,dp,c 求明文m(dp泄露)[buu RSA2题]
小记一下:
dp=d%(p-1)
dq=d%(q-1)
dp*e = i*(p-1)+1
1 | from gmpy2 import * |
已知p,q,e,n,文件加密密文 求密文m [buu RSA题]
e= 65537
n=86934482296048119190666062003494800588905656017203025617216654058378322103517
p= 285960468890451637935629440372639283459
q= 304008741604601924494328155975272418463
d=81176168860169991027846870170527607562179635470395365333547868786951080991441
enc文件不能直接读,应该用代码读
1 | from Crypto.Util.number import bytes_to_long |
已知p+q,(p+1)*(q+1),c,d求明文m([GUET-CTF2019]BabyRSA )
(p+1)(q+1)=pq+1+p+q
n=p*q
m=c^d mod n
写个脚本
1 | from libnum import n2s |
Dangerous RSA(低加密指数攻击)
sa 的加密 为 c = m ^ e mod n
当e 很小,n很大 时,有两种情况
m ^ e 有可能小于 n 。 此时, c = m ^ e 。 密文 m = c 开e次方
当 m ^ e > n 。 此时。 m ^ e = kn + c 。 k 是整数 。对 k 进行爆破,就能找到对应的m
1 | #python3 |
iroot(c+k*n,e)为c+k*n开e次方
mpz用来处理大整数和需要高精度运算
RSAROLL(rsa)
题目信息没看懂,找大佬的wp才知道{920139713,19},一个是n,一个是e,后面那一大串是拆分的c
我们通过网站分解n得到
p= 18443
q=49891
所以已知信息有
p= 18443
q=49891
n=920139713
e=19
我们写脚本来爆c
1 | import libnum |
得到flag
1 | flag{13212je2ue28fy71w8u87y31r78eu1e2} |
rsa2
源码长这样,我们需要将N分解为p和q
p=9046853915223503351787031888977627106934564043204783593118678181991596316582877057556463152579621699010610569526573031954779520781448550677767565207407183
q=11273732364123571293429600400343309403733952146912318879993851141423284675797325272321856863528776914709992821287788339848962916204774010644058033316303937
然后改一下代码
1 | N = 101991809777553253470276751399264740131157682329252673501792154507006158434432009141995367241962525705950046253400188884658262496534706438791515071885860897552736656899566915731297225817250639873643376310103992170646906557242832893914902053581087502512787303322747780420210884852166586717636559058152544979471 |
根据原题处理d值并输出
这里就是按照原题给的计算式去处理d值,这里有个小坑,就是由于Python2和Python3有一点区别,在Python3中,hex(d)得到的值在输出形式上相比Python2少了一个末尾的L,再用这个值去做hash得到的md5值也就不同了。经实验发现,正确的结果可以用Python2直接得到,或在Python3中做hash时给参数末尾加上L。
rsa5(低加密指数广播攻击)
低加密指数广播攻击特点
1 | 加密指数e非常小 |
此题给出的e很小且不变,给出了不同的公钥(e,n)和对应的密文c,也就是用不同的公钥加密相同的明文m
解题思路:
不同的模数n中可能存在相同的p或者说q
求出不同n之间的最大公约数 gcd()
得到p或q 可得d
有私钥d就能得到明文
1 | import gmpy2 |
[NCTF2019]childRSA(费马小定理)
1 | from random import choice |
只在基础的RSA上修改了大素数的生成过程。choice()函数从小于10000的素数中随机挑选一个
1 | 这里primes为前10000个素数的列表 |
p,q的生成方式是一个突破口,分析函数getprime(),p,q就是在前10000个素数列表里面随机找几个素数相乘再加一得到的,所以这10000个素数的乘积x是p-1和q-1的倍数,x=k*(p-1),n=p*q,这里就要从n和x得到p。
费马小定理
1 | 若b为一个素数,则对于任意整数a,有a^(b-1) = 1 (mod b),即a^k*(b-1) = 1 (mod b) |
1 | x=k*(p-1),n=p*q |
1 | import gmpy2 |
总结:当知道某一个数x是p-1,q-1的倍数时,就用gcd(2^x-1,n)=p,进一步gcd(pow(2,x,n)-1,n)=p。
[HDCTF2019]bbbbbbrsa
可以明显的看到c是逆过来的,我们重新把c进行排序,在进行base64解码得到c
1 | from base64 import b64encode as b32encode |
rsa4(低加密指数广播攻击)
另外有两点需要注意:
1、此题中的N、c均是以5进制表示,要先用int(“*****”,5)转换为十进制才能计算(开始运行半天都不出结果,看了其他师傅博客才发现原来是五进制)。
2、题目没有给出加密指数e,但是根据低加密指数广播攻击的特性猜e=3、10、17等
1 | from Crypto.Util.number import * |
primefac.modinv(a, n)
: 这个部分使用primefac
库中的modinv
函数,来计算a
在模n
意义下的逆元素。这意味着找到一个数x
,使得 (a * x) % n = 1
[BJDCTF2020]rsa_output
我们审计题目,发现题目给了我们两个一样的m和两个不一样的e和c,我们考虑共模攻击,
c1 = m^e1 mod n =>c1^s1 = m^(e1*s1) mod n
c2 = m^e2 mod n =>c2^s2 = m^(e2*s2) mod n
两者相乘,通过扩展欧几里得定理,我们可知e1与e2互质,必存在s1和s2使e1s1+e2s2=1
由此可求出相对应的s1和s2.
m=(c1*s1+c2*s2)%n
1 | n=21058339337354287847534107544613605305015441090508924094198816691219103399526800112802416383088995253908857460266726925615826895303377801614829364034624475195859997943146305588315939130777450485196290766249612340054354622516207681542973756257677388091926549655162490873849955783768663029138647079874278240867932127196686258800146911620730706734103611833179733264096475286491988063990431085380499075005629807702406676707841324660971173253100956362528346684752959937473852630145893796056675793646430793578265418255919376323796044588559726703858429311784705245069845938316802681575653653770883615525735690306674635167111 |
[BJDCTF2020]RSA
1 | from Crypto.Util.number import getPrime,bytes_to_long |
我们发现第一个n和第二个n共用一个q,因此我们通过gcd可以得到q的值,从而得到p的值,又已知pow(294,e,n)的值,因此我们可以爆破出e的值
1 | from Crypto.Util.number import getPrime, bytes_to_long, long_to_bytes |
[GWCTF 2019]BabyRSA(解方程)
1 | import hashlib |
求得p和q
接着求d
1 | d=gmpy2.invert(e,(p-1)*(q-1)) |
然后可以求c1,c2
1 | c1=pow(m1,d,N) |
然后联立方程,求得F1,F2
1 | F1=Symbol('F1') |
最后转为字节
1 | import gmpy2 |
SameMod(共模攻击)
模攻击
共模是指:就是明文m,相同。用两个公钥e1,e2加密得到两个私钥d1,d2 和两个密文c1,c2
共模攻击,即当m不变的情况下,知道n,e1,e2,c1,c2, 可以在不知道d1,d2的情况下,解出m
利用条件为=> gcd(e1,e2)=1
根据扩展欧几里得 算法得
可以得到该式子的一组解(s1,s2) 假设s1为正数,s2为负数
有整数s1,s2(一正一负)
存在e1s1+e2s2==1
1 | from Crypto.Util.number import long_to_bytes |
我们发现输出是一串乱码,但当我们看到m的值,发现里面有ascii码的影子
我们进行解码
1 | from Crypto.Util.number import long_to_bytes |
得到flag
[AFCTF2018]可怜的RSA(rsa公钥加密)
我们先利用Crypto.PublicKey的RSA模块从key文件中获取公钥信息n,e
1 | from Crypto.PublicKey import RSA |
得到n,e的值后,对n进行分解,得到p和q
1 | p = 3133337 |
利用gmpy2库通过p,q,ep,q,e求d
1 | from gmpy2 import * |
打包密钥对flag.pnc解密(由于是Base64编码后的密文,因此还需解码)
1 | from Crypto.PublicKey import RSA |
[RoarCTF2019]babyRSA(威尔逊定理)
1 | import sympy |
分析
从代码中可以知道:
p=(B1!)%A1p=(B1!)%A1
q=(B2!)%A2q=(B2!)%A2
又由威尔逊定理知道,
(A−1)!≡ −1 mod A(A−1)!≡ −1 mod A
而B=A-random.randint(1e3,1e5),所以在B的前面补上
(A−1)(A−2)(A−3)…(B+1)(A−1)(A−2)(A−3)…(B+1)
就有
(A−1)(A−2)(A−3)…(B+1)∗(B!)%A=−1%A(A−1)(A−2)(A−3)…(B+1)∗(B!)%A=−1%A
于是再整理一下又有
(A−2)(A−3)…(B+1)∗(B!)%A=1%A(A−2)(A−3)…(B+1)∗(B!)%A=1%A
这就意味这可由(A−2)(A−3)…(B+1)(A−2)(A−3)…(B+1)模A的逆元求得(B!)%A(B!)%A的值。再取nextprime(sympy.ntheory.generate模块里的nextprime不是nextPrime)即可得到p或q的值。
1 | from sympy import nextprime |
RoarCTF{wm-CongrAtu1ation4-1t4-ju4t-A-bAby-R4A}
RSA & what(共模攻击&base64隐写)
我们仔细观察两个文件,发现有两个e和多个c,n是一样的,我们想到共模攻击
1 | from Crypto.Util.number import* |
得到的明文为base64编码,解码后是对base54的介绍,没啥用
我们主要看base64编码是一段一段的
不难想到base64隐写。
我们到网上找一段base64隐写脚本
1 | from Crypto.Util.number import* |
flag吧数字包起来就行了
[NPUCTF2020]EzRSA(最小公倍数(p,q) ∗ 最大公因数(p,q) = p∗q)
根据题设,我们得到以下关系
1 | gift=lcm((p-1)*(q-1)) |
由小学五年级的知识,有
1 | 最小公倍数(p,q) ∗ 最大公因数(p,q) = p∗q |
所以对于gift
有
我们可以求的gift的二进制位数为2045
1 | print(len(bin(gift)[2:])) |
同时我们知道ϕ(n)的位数为2048,因此gcd(p−1,q−1)gcd(p−1,q−1)占3bits,因此最大公因数的范围(十进制)为[4,8]
我们在此范围内遍历最大公因数的值,然后与最小公倍数相乘得到ϕ(n)的值,然后通过逆模运算求得d,然后就可得·明文
但需要注意这里的e不是素数,分解可得e=2*27361
所以在计算时,我们要先将e除以2
值的变化可通过以下表达式体现
所以解出的明文需要开根号再转为字节流
注意:遍历过程中不是所有的值都符合条件,可能会报ZeroDivisionError,因此需要加异常处理
1 | from Crypto.Util.number import * |
[MRCTF2020]babyRSA
由 gen_q()函数我们可以直接得出_Q的值:
1 | Q = sub_Q ** Q_2 % Q_1 |
我们观察gen_p
1 | def gen_p(): |
它通过循环生成了17个素数,并且给了第九个素数的值,我们可以逆推和顺推得到其余16个素数的值
然后n将17个素数乘在一起
有欧拉函数
那我们就可以得到_p的值
既然已知_Q和_P,我们就能得到flag
1 | import gmpy2 |
[MRCTF2020]Easy_RSA
求P:
1 | n=p*q |
已知p+q和p*q,我们就能得到(p+q)和(p-q)的平方,然后开根解方程即可
求Q:
与求P不同:此处无φ(n),只有Q_E_D,
根据e*d mod φ(n) =1 来求φ(n)
首先:
φ(n)=(p-1)*(q-1)
e*d = kφ(n) +1=k(pq -p -q +1) +1 ==> k = (e * d -1)/(pq - p - q +1)
k值无法确定,上式难以求解。
p,q均为大质数,并且1<< p < q, 那么:
(pq - p - q +1) ≈( p-2)q≈ pq
k = (e * d -1)/(pq - p - q +1) ≈ (Q_E_D -1)/Q_n
由于分母放大,所求k值略小: k = ((Q_E_D-1)//Q_n)+1
则可求解Q
exp
1 | import gmpy2,sympy |
[HDCTF2019]together(base64与unicode之间的转换以及共模攻击)
题目给了四个文件
两个密文,那个公钥
我们先看两个公钥的n和e
我们用kail的openssl进行解码
1 | openssl rsa -pubin -text -modulus -in warmup -in pubkey1.pem |
或者用python脚本进行读取
1 | from Crypto.PublicKey import RSA |
得到两个公钥的n和e
1 | pubkey1.pem |
我们可以发现n相同,但e不同,这里一个考的是共模攻击
然后将my_flag1和my_flag2用随波逐流进行base64转16进制,得到c1和c2
1 | c1=0x52334e6f79367233574c49747974416d6234466d484579676f696c756345455a624f395a595878354a4e3033484e70424c44783766586432666c2b554c352b31315243732f7930716c5447555257574474473636654e4c7a47774e70414b69566a3649375274554a6c3250636d334e764665414677493955735652457968377a4956367349395a50386c2f324756446f724c417a35554c572b66304f494e47684a6d5a6d38464c2f61446e6c6654456c685138374c506963577058596f4d747972365772786a4b364f6e746e384271437430456a51375465585a6878494839565450576a446d46646d4f716171645649542b4c5a656d54674c4e4553774d356e6e346735533361464446776a31596944596c302f2b386574764b664f72666f4b4f7752304378735248616777645555544553384563484c6d4d474378436b445a6e33537a6d6d41364e62336c674c65536747385031413d3d |
然后我们进行rsa解密
1 | from Crypto.Util.number import long_to_bytes |
得到flag
[INSHack2017]rsa16m(低加密指数广播攻击)
通过md文件提示我们可以知道n非常非常非常大
我们推测这题为低密度指数加密攻击,直接将n进行开方
1 | import gmpy2 |
[NPUCTF2020]认清形势,建立信心
1 | from Crypto.Util.number import * |
已知
m1 =2^e^ mod n
m2 =2^2e^ mod n
m3 =2^3e^ mod n
我们可得
m2=m1^2^ + k1*n
m3=m1*m2+k2*n
所以 n =gcd(m1^2^-m2,m1*m2-m3)
之后用yafu分解n,正常rsa就行
1 | from Crypto.Util.number import* |
discrete_log(n,a,b)
b^x^ ≡ a mod n
在计算离散对数时,要求底数(基数)和模数必须是互质的,即n和b的最大公约数(gcd)应为 1
[De1CTF2019]babyrsa(中国剩余定理&e与phi不互质&低加密&裴蜀定理)
这个题分为四步来写
第一步
代码最上面一层给了4组n和c,估计是中国剩余定理
中国剩余定理的python脚本如下:
1 | import gmpy2 |
注意中国剩余定理直接算出来的结果其实是p的4次方,要使用gmpy2.iroot()函数进行4次开方
第二步
我们要对ee2=3很敏感,低加密指数一般是个与坡口,我们再观察tmp和n的相对大小,我们发现tmp的3次方于n大小相等
已知
k*n+c*e*2=(e2+tmp)**3
那么就可以爆破k的大小来获取e2
1 | import gmpy2 |
按经验来说,e2一般不是一个太大的数,输出有很多,从正到负的都有,我们想要的就是输出刚刚从负到正的那个值
可得
1 | e2=381791429275130 |
随后是解e1:
仔细观察可以发现ce1的值与n的值相差了数十个数量级,从概率统计的意义上讲,如果比n小的每个数作为结果的可能相同,那么这种事情发生的概率非常小,但是还有一种可能就是,由于e1很小,e1的42次方都比n小,从而导致模n没起效果。
我们试着给ce1开42次方,果然得到了一个差不多的整数,证实了猜想
1 | e1=15218928658178 |
第三步
只给了e,n,c,这样一般是没办法直接得到明文的,这种情况下只能看看n可不可以用yafu分解,或者暴力分解
嗯,是可以的
那么此题的hint也成功解出来了
hint
emmmm,浪费表情
第四步
e与phi不互质
1 | assert(c1==pow(flag,e1,p*q1)) |
1 | q1 = 127587319253436643569312142058559706815497211661083866592534217079310497260365307426095661281103710042392775453866174657404985539066741684196020137840472950102380232067786400322600902938984916355631714439668326671310160916766472897536055371474076089779472372913037040153356437528808922911484049460342088834871 |
总exp
1 | import gmpy2 |
参考:
https://blog.csdn.net/shshss64/article/details/127403833
https://blog.csdn.net/a5555678744/article/details/117308377
[NPUCTF2020]共 模 攻 击(共模攻击&Coppersmith定理)
hint
1 | from gmpy2 import * |
已知c1,c2,e1,e2,n,我们可以直接用共模攻击求出c,然后就是
c ≡ m^256^ mod n
我们需要求m,我们可以用sympy库中的nthroot_mod(c,e,n)函数 ,
nthroot_mod
主要用于在模运算下求解某个数的 n 次方根
1 | from Crypto.Util.number import long_to_bytes |
我们知道了m的比特位少于400
我们来看task
1 | from gmpy2 import * |
塞个大佬博客
1 | sage |
定义大数 a
, b
, 和 n
: 这三个大数分别是多项式的系数和模数。你要解决的是一个二次多项式 f(x)=x2−a⋅x+bf(x) = x^2 - a \cdot x + bf(x)=x2−a⋅x+b,其中 aaa 和 bbb 是给定的大数,n
是模数。
SageMath 环境设置: R.<x> = Zmod(n)[]
这行代码的意思是:
Zmod(n)
表示在模 nnn 的有限域中进行计算。R.<x>
创建了一个多项式环R
,并定义了x
作为多项式中的变量。
这样,你就可以在模 nnn 上进行多项式运算了。
定义多项式 f
: f = x^2 - a*x + b
定义了一个二次多项式 f(x)=x2−a⋅x+bf(x) = x^2 - a \cdot x + bf(x)=x2−a⋅x+b。这个多项式是你需要求根的对象。
查找小根: f.small_roots(X=2^400)
这行代码的作用是通过 small_roots
方法查找多项式 f(x)
在模 nnn 下的根。X=2^400
表示你希望在一个非常大的范围内查找根,具体范围为 24002^{400}2400,这是一个用于限制查找的参数。
small_roots
是一个算法,用来快速寻找多项式的根,特别是在给定模数时,能够有效地搜索出符合条件的“较小”的根。
最后转换
1 | from Crypto.Util.number import long_to_bytes |
得到flag
[羊城杯 2020]RRRRRRRSA(wiener attack )
wiener attack 是依靠连分数进行的攻击方式,适用于非常接近某一值(比如1)时,求一个比例关系,通过该比例关系再来反推关键信息就简单很多。这种攻击对于解密指数d很小时有很好的效果,一般的用法是通过
ed mod phi(N)=1
得到 ed=k*phi(N)+1
即 e/phi(N)=k/d+1/phi(N)
这种情况下phi(N)≈N,且phi(N)非常大
所以有 e/N - k/d = 1/phi(N),也就是说k/d与e/N非常接近,而e/N又是已知的
对e/N进行连分数展开,得到的一串分数的分母很有可能就是d(论文太难了,只能记结论了T_T),只要检验一下
ed mod phi(N)
看它是不是1就知道对不对了。
但是这道题倒是告诉我,wiener attack的利用并不一定是这样的方式,只要其他值符合类似的条件,也可以试着求出一个关键值。
另外注意:wiener attack使用是要满足一定数值条件的,对d和N的相对大小,以及p,q的相对大小都是有要求的
先看看题干,明显可以发现加密指数e非常大,有经验就晓得这和wiener attack脱不了干系。
代码的逻辑也很好理解,先是把flag分成两部分(其实两部分加密方式是一样的),然后生成两个非常接近的大素数P1,P2,然后生成了两个相邻的较小的大素数,用P1的平方和Q1相乘得到N1,N2同理。用两个相近巨大的加密指数E加密。
1 | import hashlib |
但是和普通的wiener attack 不同的是,e与N并没有近到相除约为1的地步,相差还是很大的,也就是说解密指数d也许还是很大的,
这样就解不出来。
这道题有意思的部分就在于,e和N的关系不符合利用条件,但是N1和N2的关系却适合
对于这一道题:
N1/N2=(P1/P2)^2^ * (Q1/Q2)
显然我们可以知道的是N1/N2 <Q1/Q2所以在Q1/Q2在区间(N1/N2,1)之间 (这是关键)
尝试对N1/N2进行连分数展开并求其各项渐进分数,其中某个连分数的分母可能就是Q1(这个可以依靠N%Q来验证)
连分数生成
1 | def continuedFra(x, y): #不断生成连分数的项 |
寻找合适的Q1
1 | def wienerAttack(e, n): |
最后的解密.
找到Q1后顺势就可以求出所有其他参数
1 | from Crypto.Util.number import * |
[AFCTF2018]花开藏宝地
给了5个压缩包和提示
misc爷的事,直接叫个misc佬把压缩包解了
5个压缩包分别考的是数字爆破,小写字母爆破,大写字母爆破,无密码,ntfs流查看
每个压缩包里给了两组数据
我们解前三个压缩包,得到
1 | x1 = 305345133911395218573790903508296238659147802274031796643017539011648802808763162902335644195648525375518941848430114497150082025133000033835083076541927530829557051524161069423494451667848236452337271862085346869364976989047180532167560796470067549915390773271207901537847213882479997325575278672917648417868759077150999044891099206133296336190476413164240995177077671480352739572539631359 |
所以,这个东西是什么。。?
了解了一个新的知识点,叫门限方案
参考:密码学协议举例(二):秘密共享的门限方案 | Matrix67: The Aha Moments
门限方案也有很多种,参考:
Secret Sharing - Web Encrypt
所以y’即可通过对五组数据中任意三组使用中国剩余定理得到,p在题面中给出了,只需要用 y’mod p 即可得到flag
1 | y1 = 305345133911395218573790903508296238659147802274031796643017539011648802808763162902335644195648525375518941848430114497150082025133000033835083076541927530829557051524161069423494451667848236452337271862085346869364976989047180532167560796470067549915390773271207901537847213882479997325575278672917648417868759077150999044891099206133296336190476413164240995177077671480352739572539631359 |
[MoeCTF2022]signin(e与phi不互质)
1 | from Crypto.Util.number import * |
我们发现gcd(e,phi)=65537,e与phi不互质,但我们发现e与p-1互质
m = c ^ d mod n
==>
m = c ^ d mod p
m = c ^ d mod q
(注:此推论满足的前提是——在c不是p或q的倍数,以及d是正整数的情况下,m = c ^ d modp 和m = c ^ d modq 总是成立的,有兴趣的同志们可以自行查找推导过程,这里就不过多说了)
故有以下结论
1 | 故可以使用以下代码: |
1 | from Crypto.Util.number import * |