密码学寒假第三周

密码学寒假第三周

安装并配置sagemath

找到安装网址SageMath Download - win (tsinghua.edu.cn)

下载安装后出现

数论学习

欧拉函数

phi_n:小于n的自然数中与n互质的数的个数

质数a:phi_a=a-1

欧拉定理

n,a为两个互质的正整数
a Φ ( n ) ≡ 1. m o d . n a^{Φ(n)}≡1.mod.n aΦ(n)1.mod.n

费马小定理

p为质数,a与p互质,a^p≡a (mod p),a^(p-1)≡1 (mod p)

逆元(模反数)

a mod p的逆元是可以使a*a’ mod p=1的最小a’

模运算

类似于四则运算

(a + b) % p = (a % p + b % p) % p
(a - b) % p = (a % p - b % p) % p
(a * b) % p = (a % p * b % p) % p
a ^ b % p = ((a % p) ^ b) % p
结合律
((a + b) % p + c) = (a + (b + c) % p) % p
((a * b) % p * c) = (a * (b * c) % p) % p
交换律
(a + b) % p = (b + a) % p
(a * b) % p = (b * a) % p
分配律
(a + b) % p = (a % p + b % p) % p
((a + b) % p * c) % p = ((a * c) % p + (b * c) % p
重要定理
若 a ≡ b (mod p),则对于任意的 c,都有(a + c) ≡ (b + c) (mod p)
若 a ≡ b (mod p),则对于任意的 c,都有(a * c) ≡ (b * c) (mod p)
若 a ≡ b (mod p),c ≡ d (mod p),则
(a + c) ≡ (b + d) (mod p)
(a - c) ≡ (b - d) (mod p)
(a * c) ≡ (b * d) (mod p)
(a / c) ≡ (b / d) (mod p)

RSA推导

在B站大学上跟着写下的推导

基础题型

c =
p =
q =
e =
n =
phi_n=(p-1)*(q-1)
d=gmpy2.invert(e,phi_n)
m=pow(c,d,n)
print(m)
print(libnum.n2s(int(m)))

共模攻击

n=
e1=
e2=
c1=
c2=
s1,s2,s3=gmpy2.gcdext(e1,e2)#扩展欧几里得定理
m=(pow(c1,s2,n)*pow(c2,s3,n)%n)
print(libnum.n2s(int(m)))

低加密指数攻击

import gmpy2
import libnum

def de(c, e, n):
    k = 0
    while True:
        mm = c + n*k
        result, flag = gmpy2.iroot(mm, e)
        if True == flag:
            return result
        k += 1
n=
e=
c=
m=de(c,e,n)
print(m)
print(libnum.n2s(int(m)).decode())

N不互素

N1,N2使用相同的素数p或q,相同e(65537),m,有两个或多个n,c时,可以考虑N不互素。

e=
n1=
c1=
n2=
c2=
q=gmpy2.gcd(n1,n2)#N1,N2使用相同的素数p或q
p1=n1//q
phi_n=(q-1)*(p1-1)
d1=libnum.invmod(e,phi_n)#求逆元
m=pow(c1,d1,n1)
print(m)
print(libnum.n2s(int(m)).decode())

dp泄露

一般题目中会给出n,e,c,dp
那么这种题型的特点就是有dp

import libnum
import gmpy2

n=
e= 
dp= 
c=
#遍历,爆破出p
#dp*e-1=(p-1)*[k2*(q-1)-k1]
#i=[k2*(q-1)-k1]
for i in range(1,65535):
    p=(dp*e-1)//i+1
    if n%p==0:
        q=n//p
        break
print(p)
print(q)
phi_n= (p-1)*(q-1)
d=gmpy2.invert(e,phi_n)
m=pow(c,d,n)
print(m)
flag=libnum.n2s(int(m)).decode()
print(flag)

ctf-show rsa

easy RSA7

CopperSmith攻击
特点:“p>>128<<128"且p末尾很多0,p低位数据缺失
理解p>>128<<128:利用代码,由简入繁
printp>>3 p<<3 p>>3<<3
运行查看结果,对比更好理解p>>128<<128

先使用sagemath运行下面这段代码可以得到n,p,q

from sage.all import *
n = 0x79e0bf9b916e59286163a1006f8cefd4c1b080387a6ddb98a3f3984569a4ebb48b22ac36dff7c98e4ebb90ffdd9c07f53a20946f57634fb01f4489fcfc8e402865e152820f3e2989d4f0b5ef1fb366f212e238881ea1da017f754d7840fc38236edba144674464b661d36cdaf52d1e5e7c3c21770c5461a7c1bc2db712a61d992ebc407738fc095cd8b6b64e7e532187b11bf78a8d3ddf52da6f6a67c7e88bef5563cac1e5ce115f3282d5ff9db02278859f63049d1b934d918f46353fea1651d96b2ddd874ec8f1e4b9d487d8849896d1c21fb64029f0d6f47e560555b009b96bfd558228929a6cdf3fb6d47a956829fb1e638fcc1bdfad4ec2c3590dea1ed3
p4 = 0xd1c520d9798f811e87f4ff406941958bab8fc24b19a32c3ad89b0b73258ed3541e9ca696fd98ce15255264c39ae8c6e8db5ee89993fa44459410d30a0a8af700ae3aee8a9a1d6094f8c757d3b79a8d1147e85be34fb260a970a52826c0a92b46cefb5dfaf2b5a31edf867f8d34d22229
#p4为p去除0的剩余位e = 0x10001
pbits = 1024
kbits = pbits - p4.nbits()
print(p4.nbits())
p4 = p4 << kbits
PR.<x> = PolynomialRing(Zmod(n))
f = x + p4
roots = f.small_roots(X=2^kbits, beta=0.4)
if roots:        
    p = p4+int(roots[0]) 
    print("n= "+str(n))
    print("p= "+str(p))
    print("q= "+str(n//p))
n=15385662500833683624078569984373213422422207212280496601444231671573448637150116227706836878878073499171848761705319193774526502237353076168018030771746205464158669320919641325288612751372670181299665139997586553315310347588233406828542606020800241161051008288437407736979922757405068072731770582498252049192877898003964488874889716478031688573585352005147285581281920852472734014864246643866812388198283781144177102040492746134555811828205526783046568167440811490128574493943480402635123221242083843427421730093351014697575278810518905300063354048399554869181858023737364977648594835522202515445612655483110199795411
p=147305526294483975294006704928271118039370615054437206404408410848858740256154476278591035455064149531353089038270283281541411458250950936656537283482331598521457077465891874559349872035197398406708610440618635013091489698011474611145014167945729411970665381793142591665313979405475889978830728651549052207969
q=104447286451939566076017797038369998283019120860149982200602344749600436385708441695230995780714906769626731151644722579252428917819367256207463696691033967714073069435280785389775459281272218174741165454138432242201951151298026448827619971129737985262978620243577274864410816225725466321200461416855483876019

现在我们已知n,p,q,e,c
套个基础脚本即得到flag

import libnum
import gmpy2
import binascii
n=15385662500833683624078569984373213422422207212280496601444231671573448637150116227706836878878073499171848761705319193774526502237353076168018030771746205464158669320919641325288612751372670181299665139997586553315310347588233406828542606020800241161051008288437407736979922757405068072731770582498252049192877898003964488874889716478031688573585352005147285581281920852472734014864246643866812388198283781144177102040492746134555811828205526783046568167440811490128574493943480402635123221242083843427421730093351014697575278810518905300063354048399554869181858023737364977648594835522202515445612655483110199795411
p=147305526294483975294006704928271118039370615054437206404408410848858740256154476278591035455064149531353089038270283281541411458250950936656537283482331598521457077465891874559349872035197398406708610440618635013091489698011474611145014167945729411970665381793142591665313979405475889978830728651549052207969
q=104447286451939566076017797038369998283019120860149982200602344749600436385708441695230995780714906769626731151644722579252428917819367256207463696691033967714073069435280785389775459281272218174741165454138432242201951151298026448827619971129737985262978620243577274864410816225725466321200461416855483876019
c=0x1b2b4f9afed5fb5f9876757e959c183c2381ca73514b1918d2f123e386bebe9832835350f17ac439ac570c9b2738f924ef49afea02922981fad702012d69ea3a3c7d1fc8efc80e541ca2622d7741090b9ccd590906ac273ffcc66a7b8c0d48b7d62d6cd6dd4cd75747c55aac28f8be3249eb255d8750482ebf492692121ab4b27b275a0f69b15baef20bf812f3cbf581786128b51694331be76f80d6fb1314d8b280eaa16c767821b9c2ba05dfde5451feef22ac3cb3dfbc88bc1501765506f0c05045184292a75c475486b680f726f44ef8ddfe3c48f75bb03c8d44198ac70e6b7c885f53000654db22c8cee8eb4f65eaeea2da13887aaf53d8c254d2945691
e=0x10001

phi = (q-1)*(p-1)
d = gmpy2.invert(e,phi)
m = gmpy2.powmod(c,d,n)
print(libnum.n2s(int(m)))

easy RSA8

先将下载的压缩包解压到相应的文件夹中,网上套用一个解题脚本

from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP #PKCS1 OAEP 是一种基于 RSA 和 OAEP 填充的非对称密码
from numpy import long
import gmpy2
import binascii

读取文件可以得到n,e

public = RSA.importKey(open('public.key').read())
n = long(public.n)
e = long(public.e)
print(n)
print(e)

利用在线网站factordb.com分解n,得到p,q

p = 97
q = 106249972159566919549855203174197828387397831115262336234662051342543151219702510584956705611794290291345944183845955839244363030579896461607496959399297130227066841321473005074379950936513608503266587950271044991876848389878395867601515004796212227929894460104645781488319246866661398816686697306692491058609
d = 4520639064487098151327174667961365516283539231992543792882057746866179464294032313887767783621724945557985447874376379715922452725597335427159165685648572663979688014560576024497341124412004366514253110547369977143739781801290219136578513871764574450392367530817034216313429071683911546803031169524669257788417
rsakey = RSA.importKey(open('public.key', 'r').read())
privatekey = RSA.construct((n,e,d,p,q))
rsa = PKCS1_OAEP.new(privatekey)
m = rsa.decrypt(open('flag.enc', 'rb').read())
print(m)

funny RSA1
N1,N2使用相同的素数pq,相同e(一般为65537)和m,有两个或多个n,c时,可以考虑N不互素。

e1 = 14606334023791426
p1 = 121009772735460235364940622989433807619211926015494087453674747614331295040063679722422298286549493698150690694965106103822315378461970129912436074962111424616439032849788953648286506433464358834178903821069564798378666159882090757625817745990230736982709059859613843100974349380542982235135982530318438330859
q1 = 130968576816900149996914427770826228884925960001279609559095138835900329492765336419489982304805369724685145941218640504262821549441728192761733409684831633194346504685627189375724517070780334885673563409259345291959439026700006694655545512308390416859315892447092639503318475587220630455745460309886030186593
c1 = 11402389955595766056824801105373550411371729054679429421548608725777586555536302409478824585455648944737304660137306241012321255955693234304201530700362069004620531537922710568821152217381257446478619320278993539785699090234418603086426252498046106436360959622415398647198014716351359752734123844386459925553497427680448633869522591650121047156082228109421246662020164222925272078687550896012363926358633323439494967417041681357707006545728719651494384317497942177993032739778398001952201667284323691607312819796036779374423837576479275454953999865750584684592993292347483309178232523897058253412878901324740104919248

e2 = 13813369129257838
p2 = 121009772735460235364940622989433807619211926015494087453674747614331295040063679722422298286549493698150690694965106103822315378461970129912436074962111424616439032849788953648286506433464358834178903821069564798378666159882090757625817745990230736982709059859613843100974349380542982235135982530318438330859
q2 = 94582257784130735233174402362819395926641026753071039760251190444144495369829487705195913337502962816079184062352678128843179586054535283861793827497892600954650126991213176547276006780610945133603745974181504975165082485845571788686928859549252522952174376071500707863379238688200493621993937563296490615649
c2 = 7984888899827615209197324489527982755561403577403539988687419233579203660429542197972867526015619223510964699107198708420785278262082902359114040327940253582108364104049849773108799812000586446829979564395322118616382603675257162995702363051699403525169767736410365076696890117813211614468971386159587698853722658492385717150691206731593509168262529568464496911821756352254486299361607604338523750318977620039669792468240086472218586697386948479265417452517073901655900118259488507311321060895347770921790483894095085039802955700146474474606794444308825840221205073230671387989412399673375520605000270180367035526919

观察题目,p1=p2,有两个不同的n,c,可以猜测为n不互素的情况,但是这道题有两个不同的e
我们先化简e,找到他们的最大公因数,分别约去14得到新的e1,e2,由于m^e mod n =c,改变了e,对应的密文c也需要改变。

import libnum
import gmpy2
import  binascii
 
p1=121009772735460235364940622989433807619211926015494087453674747614331295040063679722422298286549493698150690694965106103822315378461970129912436074962111424616439032849788953648286506433464358834178903821069564798378666159882090757625817745990230736982709059859613843100974349380542982235135982530318438330859
q1=130968576816900149996914427770826228884925960001279609559095138835900329492765336419489982304805369724685145941218640504262821549441728192761733409684831633194346504685627189375724517070780334885673563409259345291959439026700006694655545512308390416859315892447092639503318475587220630455745460309886030186593
e=1043309573127959 #e=e1/14
c1=11402389955595766056824801105373550411371729054679429421548608725777586555536302409478824585455648944737304660137306241012321255955693234304201530700362069004620531537922710568821152217381257446478619320278993539785699090234418603086426252498046106436360959622415398647198014716351359752734123844386459925553497427680448633869522591650121047156082228109421246662020164222925272078687550896012363926358633323439494967417041681357707006545728719651494384317497942177993032739778398001952201667284323691607312819796036779374423837576479275454953999865750584684592993292347483309178232523897058253412878901324740104919248
n1=p1*q1
phi_n=(p1-1)*(q1-1)
d1=gmpy2.invert(e,phi_n)
c1_14=pow(c1,d1,n1)#相当于一次解密,得到新的e对应的c
#c=pow(m,e,n)
 
#与上面的处理相同
e2 = 986669223518417
p2 = 121009772735460235364940622989433807619211926015494087453674747614331295040063679722422298286549493698150690694965106103822315378461970129912436074962111424616439032849788953648286506433464358834178903821069564798378666159882090757625817745990230736982709059859613843100974349380542982235135982530318438330859
q2 = 94582257784130735233174402362819395926641026753071039760251190444144495369829487705195913337502962816079184062352678128843179586054535283861793827497892600954650126991213176547276006780610945133603745974181504975165082485845571788686928859549252522952174376071500707863379238688200493621993937563296490615649
c2 = 7984888899827615209197324489527982755561403577403539988687419233579203660429542197972867526015619223510964699107198708420785278262082902359114040327940253582108364104049849773108799812000586446829979564395322118616382603675257162995702363051699403525169767736410365076696890117813211614468971386159587698853722658492385717150691206731593509168262529568464496911821756352254486299361607604338523750318977620039669792468240086472218586697386948479265417452517073901655900118259488507311321060895347770921790483894095085039802955700146474474606794444308825840221205073230671387989412399673375520605000270180367035526919
n2=p2*q2
phi_n2=(p2-1)*(q2-1)
d2=gmpy2.invert(e2,phi_n2)
c2_14=pow(c2,d2,n2)
#得到新的e1,e2对应的c1,c2 
print("c1=",c1_14)
print("c2=",c2_14)

得到c1,c2后,需要将其合并为c3
n=p*q,根据数论知识,q相同可以舍去。

c 1 = m 14 . m o d . q 1 c 2 = m 14 . m o d . q 2 c_1=m^{14}.mod.q_1\\c_2=m^{14}.mod.q_2 c1=m14.mod.q1c2=m14.mod.q2
根据中国剩余定理
c 3 = m 14 . m o d . ( q 1 ∗ q 2 ) c_3=m^{14}.mod.(q_1*q_2) c3=m14.mod.(q1q2)
有c1,c2时,可以运用中国剩余定理求c3

import libnum
c1=
c2=
q1=
q2=
c3=libnum.solve_crt([c1,c2], [q1,q2])#中国剩余定理
print("c3=",c3)
import libnum
import gmpy2
c3=
e=14#e没有化到最简时,逆元不存在。  14=2*7
p=#q1
q=#q2
n=p*q
phi_n=(p-1)*(q-1)
d=gmpy2.invert(e,phi_n)
c4=pow(c3,d,n)
print(c4)

同样的方法继续化简e,最终得到新e所对应的c4
e=2时
c = m 2 . m o d . n c=m^2.mod.n c=m2.mod.n
由肉眼观察,得知m^2<n=p*q
所以c=m^2
最后将c4开方就得到了m
在这里插入图片描述

在这里插入图片描述

funny RSA2

这道题与众不同的点在于将n分解成了三个数

from Crypto.Util.number import *
import gmpy2

n = 897607935780955837078784515115186203180822213482989041398073067996023639
c = 490571531583321382715358426750276448536961994273309958885670149895389968
e = 0x10001
p = 876391552113414716726089
q = 932470255754103340237147
r = 1098382268985762240184333


phi = (p - 1) * (q - 1) * (r - 1)
d = gmpy2.invert(e, phi)
m = pow(c, d, n)
print(m)
print(libnum.n2s(int(m)))

所以将N分解为多个素数的题型与这类大同小异,只是在欧拉函数phi_n的计算上扩开了一点点

import libnum
import gmpy2

n=
e=
c=

#分解n
p=
q=
r=
phi_n=(p-1)*(q-1)*(r-1)
d=gmpy2.invert(e,phi_n)
m=pow(c,d,n)
print(m)
print(libnum.n2s(int(m)))

funny RSA3

dp泄露,已知e,n,c,dp

套用之前找到的脚本。

import libnum
import gmpy2

e = 65537
n = 13851998696110232034312408768370264747862778787235362033287301947690834384177869107768578977872169953363148442670412868565346964490724532894099772144625540138618913694240688555684873934424471837897053658485573395777349902581306875149677867098014969597240339327588421766510008083189109825385296069501377605893298996953970043168244444585264894721914216744153344106498382558756181912535774309211692338879110643793628550244212618635476290699881188640645260075209594318725693972840846967120418641315829098807385382509029722923894508557890331485536938749583463709142484622852210528766911899504093351926912519458381934550361
dp = 100611735902103791101540576986246738909129436434351921338402204616138072968334504710528544150282236463859239501881283845616704984276951309172293190252510177093383836388627040387414351112878231476909883325883401542820439430154583554163420769232994455628864269732485342860663552714235811175102557578574454173473
c = 6181444980714386809771037400474840421684417066099228619603249443862056564342775884427843519992558503521271217237572084931179577274213056759651748072521423406391343404390036640425926587772914253834826777952428924120724879097154106281898045222573790203042535146780386650453819006195025203611969467741808115336980555931965932953399428393416196507391201647015490298928857521725626891994892890499900822051002774649242597456942480104711177604984775375394980504583557491508969320498603227402590571065045541654263605281038512927133012338467311855856106905424708532806690350246294477230699496179884682385040569548652234893413
#遍历,爆破出p
#dp*e-1=(p-1)*[k2*(q-1)-k1]
#i=[k2*(q-1)-k1]
for i in range(1,65535):
    p=(dp*e-1)//i+1
    if n%p==0:
        q=n//p
        break
print(p)
print(q)
phi_n= (p-1)*(q-1)
d=gmpy2.invert(e,phi_n)
m=pow(c,d,n)
print(m)
flag=libnum.n2s(int(m)).decode()
print(flag)
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值