目录
各种各样的编码
crypto0(凯撒)
crypto2(jsfuck)
crypto3(aaencode)
crypto4(知p q e求d)
crypto5(知p q e c求d)
crypto6(Rabbit)
crypto7(Ook!)
crypto8(BrainFuck)
crypto9(serpent)
crypto10(quoted-printable)
crypto11(md5)
crypto12(埃特巴什码)
crypto13(多重base)
crypto14(base64编码表换表)
萌新_密码5 (当铺密码)
find the table(元素周期表加密)
RSA篇
babyrsa(知p、q、e、c 求m)
easyrsa1(大因数分解攻击)
easyrsa2(N不互素)
★ easyrsa3(共模攻击)
easyrsa4(小明文攻击)
★ easyrsa5(低解密指数攻击-维纳攻击)
easyrsa6(pq相似)
★ easyrsa7(CopperSmith攻击 低位数据缺失-知p高位)
easyrsa8(公钥解析)
★ funnyrsa1(e和phi不互素)
funnyrsa2(n多素数因子分解)
funnyrsa3(dp泄露)
★ unusualrsa1(CopperSmith攻击 低位数据缺失-知m高位)
★ unusualrsa2(Related Message Attack 同[n,e]加密线性变换后的m)
★ unusualrsa3(多项式RSA)
★ unusualrsa4(考察数学原理 已知e、d、q模p逆)
★ unusualrsa5(e _phi不互素有限域情况)
各种各样的编码
crypto0(凯撒)
gmbh{ifmmp_dug} key为25
flag{hello_ctf}
crypto2(jsfuck)
jsfuck 编码 js 运行得到flag
crypto3(aaencode)
颜文字 aaencode解密 得到flag
crypto4(知p q e求d)
p=447685307 q=2037 e=17 flag 为 flag{d}
考察rsa求 私钥d
import gmpy2
p=447685307
q=2037
e=17
phi_n = (p-1)*(q-1)
print("d:",gmpy2.invert(e,phi_n))
# d: 53616899001
crypto5(知p q e c求d)
p=447685307 q=2037 e=17 c=704796792 flag为 flag{m}
import gmpy2
p = 447685307
q = 2037
e = 17
c = 704796792
n = p*q
phi_n = (p-1)*(q-1)
d = gmpy2.invert(e,phi_n)
print("m:",pow(c,d,n))
# m: 904332399012
crypto6(Rabbit)
密文:U2FsdGVkX19mGsGlfI3nciNVpWZZRqZO2PYjJ1ZQuRqoiknyHSWeQv8ol0uRZP94MqeD2xz+
密钥:加密方式名称
U2FsdGVkX1 开头 应该是 Rabbit加密 密钥为 Rabbit
http://www.jsons.cn/rabbitencrypt/
crypto7(Ook!)
Ook! 在线网站解密得到flag:Brainfuck/Ook! Obfuscation/Encoding [splitbrain.org]
crypto8(BrainFuck)
+++++ +++++ [->++ +++++ +++<] >++.+ +++++ .<+++ [->-- -<]>- -.+++ +++.< ++++[ ->+++ +<]>+ +++.< +++++ +++[- >---- ----< ]>--. .--.- -.-.- --.-. +++++ +..-- -..<+ +++++ +[->+ +++++ +<]>+ +.<++ ++++[ ->--- ---<] >---- ----- .---- -.<++ ++++[ ->+++ +++<] >++++ +++++ +++.< +++++ ++[-> ----- --<]> .++.- ----. <++++ +++[- >++++ +++<] >+++. --.<+ +++++ [->-- ----< ]>--- ----- ---.+ .<+++ +++[- >++++ ++<]> +++++ +++++ ++.<+ +++++ [->-- ----< ]>--- ----- ---.- .++++ .<+++ +++[- >++++ ++<]> +++++ +++.< +++++ +[->- ----- <]>-- ----- ---.- ----- .++++ +++++ .---- ----. <++++ ++[-> +++++ +<]>+ +++++ +++++ +.<++ +++[- >++++ +<]>+ ++.<
BrainFuck解密得到 flag
crypto9(serpent)
下载附件 是一个 压缩包 有密码 ARCHPR进行爆破,得到密码4132
得到一个 .dat文件 根据压缩包名称 serpent 应该是serpent加密
在线网站解密 key为4132 得到flag flag{c960a0f3bf871d7da2a8413ae78f7b5f}
Serpent Encryption – Easily encrypt or decrypt strings or files
crypto10(quoted-printable)
=E7=94=A8=E4=BD=A0=E9=82=A3=E7=81=AB=E7=83=AD=E7=9A=84=E5=98=B4=E5=94=87=E8=AE=A9=E6=88=91=E5=9C=A8=E5=8D=88=E5=A4=9C=E9=87=8C=E6=97=A0=E5=B0=BD=E7=9A=84=E9=94=80=E9=AD=82
quoted-printable编码,用一个等号”=”后跟随两个十六进制数字(0–9或A–F)来表示一个非ASCII字符
crypto11(md5)
密文:a8db1d82db78ed452ba0882fb9554fc
32位hash值,猜测md5 CMD5在线解密得到 明文:ctf
crypto12(埃特巴什码)
密文uozt{Zgyzhv_xlwv_uiln_xguhsld}
根据flag格式可知 u对应f o对应 l z对应a t对应g
埃特巴什码:最后一个字母代表第一个字母,倒数第二个字母代表第二个字母。
明文:A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
密文:Z Y X W V U T S R Q P O N M L K J I H G F E D C B A
进行替换,得到flag
直接提交不正确,a应该是A flag{Atbase_code_from_ctfshow}
crypto13(多重base)
利用脚本去帮我们 循环多次解密base
import base64
filename = r"C:\Users\lenovo\Desktop\base家族\base家族\base.txt"
with open(filename) as f:
s = f.read()
while True:
try:
s = base64.b16decode(s)
continue
except:
pass
try:
s = base64.b32decode(s)
continue
except:
pass
try:
s = base64.b64decode(s)
continue
except:
pass
break
print(s)
b'flag{b4Se_Fami1y_Is_FUn}'
crypto14(base64编码表换表)
一堆0 1 将二进制01串转换为 16进制 得到:
3333203435203530203266203333203536203465203436203436203664203465203435203431203665203663203438203434203335203634203433203464203664203536203438203434203335203631203634203339203735203437203061
hex 解码得到:
33 45 50 2f 33 56 4e 46 46 6d 4e 45 41 6e 6c 48 44 35 64 43 4d 6d 56 48 44 35 61 64 39 75 47 0a
再次解码:
得到 3EP/3VNFFmNEAnlHD5dCMmVHD5ad9uG
直接base64解码 不行,这里需要根据base64编码表 对这串代码进行一下 移位替换
看一下 我们的密文开头是 3EP/ 而flag的base64编码为:ZmxhZw==
位移刚好是30 写脚本还原一下
s= '3EP/3VNFFmNEAnlHD5dCMmVHD5ad9uG'
a = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='
flag = ''
for i in s:
flag += a[(a.index(i)-30)%64]
if len(flag)%4!=0:
flag += '='*(4-len(flag)%4)
print(flag)
print(base64.b64decode(flag).decode('UTF-8'))
#ZmxhZ3vnnIvmiJHplb/kuI3plb8/fQo=
#flag{看我长不长?}
或者换base64编码表 进行解密
A-Za-z0-9+/ 改为:
efghijklmnopqrstuvwxyz0123456789+/ABCDEFGHIJKLMNOPQRSTUVWXYZabcd
萌新_密码5 (当铺密码)
由田中 由田井 羊夫 由田人 由中人 羊羊 由由王 由田中 由由大 由田工 由由由 由由羊 由中大
当铺密码加密方式:前汉字有多少笔画出头,就是转化成数字几
find the table(元素周期表加密)
审查元素 F12 发现
没见过。。。。 看其他师傅wp才知道是 元素周期表??? wtf
9对应 F 57对应La 64对应Ga 最终得到flag:flag{doyoulikesnow}
RSA篇
babyrsa(知p、q、e、c 求m)
给了 p、q、e、c 直接RSA模板算 d 求出来m即可
import gmpy2
from Crypto.Util.number import *
e = 65537
p = 104046835712664064779194734974271185635538927889880611929931939711001301561682270177931622974642789920918902563361293345434055764293612446888383912807143394009019803471816448923969637980671221111117965227402429634935481868701166522350570364727873283332371986860194245739423508566783663380619142431820861051179
q = 140171048074107988605773731671018901813928130582422889797732071529733091703843710859282267763783461738242958098610949120354497987945911021170842457552182880133642711307227072133812253341129830416158450499258216967879857581565380890788395068130033931180395926482431150295880926480086317733457392573931410220501
c = 4772758911204771028049020670778336799568778930072841084057809867608022732611295305096052430641881550781141776498904005589873830973301898523644744951545345404578466176725030290421649344936952480254902939417215148205735730754808467351639943474816280980230447097444682489223054499524197909719857300597157406075069204315022703894466226179507627070835428226086509767746759353822302809385047763292891543697277097068406512924796409393289982738071019047393972959228919115821862868057003145401072581115989680686073663259771587445250687060240991265143919857962047718344017741878925867800431556311785625469001771370852474292194
n = p*q
phi_n = (p-1)*(q-1)
d = gmpy2.invert(e,phi_n)
m = pow(c,d,n)
print(long_to_bytes(m))
# b'flag{b4by_R5A}'
easyrsa1(大因数分解攻击)
给了 e、n、c n比较小,可以在线factor分解 得到p q
factordb.com
之后 RSA正常解密求m即可
import gmpy2
from Crypto.Util.number import *
e = 65537
n = 1455925529734358105461406532259911790807347616464991065301847
c = 69380371057914246192606760686152233225659503366319332065009
p = 1201147059438530786835365194567
q = 1212112637077862917192191913841
phi_n = (p-1)*(q-1)
d = gmpy2.invert(e,phi_n)
m = pow(c,d,n)
print(long_to_bytes(m))
# b'flag{fact0r_sma11_N}'
easyrsa2(N不互素)
同一个 e 但是题目给了两个不同的 n和c 。 公钥e和明文m 一样,因此两个n之间可能是共享素数 即p 或者 q 相同
求出n1与n2的最大公因数即为p,之后就可以得到q和d,从而求解m
ps:实际上这道题的n 在factordb.com 试了试好像也能分解
import gmpy2
from Crypto.Util.number import *
e = 65537
c = 1627484142237897613944607828268981193911417408064824540711945192035649088104133038147400224070588410335190662682231189997580084680424209495303078061205122848904648319219646588720994019249279863462981015329483724747823991513714172478886306703290044871781158393304147301058706003793357846922086994952763485999282741595204008663847963539422096343391464527068599046946279309037212859931303335507455146001390326550668531665493245293839009832468668390820282664984066399051403227990068032226382222173478078505888238749583237980643698405005689247922901342204142833875409505180847943212126302482358445768662608278731750064815
n1 = 23686563925537577753047229040754282953352221724154495390687358877775380147605152455537988563490716943872517593212858326146811511103311865753018329109314623702207073882884251372553225986112006827111351501044972239272200616871716325265416115038890805114829315111950319183189591283821793237999044427887934536835813526748759612963103377803089900662509399569819785571492828112437312659229879806168758843603248823629821851053775458651933952183988482163950039248487270453888288427540305542824179951734412044985364866532124803746008139763081886781361488304666575456680411806505094963425401175510416864929601220556158569443747
n2 = 22257605320525584078180889073523223973924192984353847137164605186956629675938929585386392327672065524338176402496414014083816446508860530887742583338880317478862512306633061601510404960095143941320847160562050524072860211772522478494742213643890027443992183362678970426046765630946644339093149139143388752794932806956589884503569175226850419271095336798456238899009883100793515744579945854481430194879360765346236418019384644095257242811629393164402498261066077339304875212250897918420427814000142751282805980632089867108525335488018940091698609890995252413007073725850396076272027183422297684667565712022199054289711
p = gmpy2.gcd(n1,n2)
q = n1//p
phi_n = (p-1)*(q-1)
d = inverse(e,phi_n)
m = pow(c,d,n1)
print(long_to_bytes(m))
# b'flag{m0_bv_hv_sv}'
★ easyrsa3(共模攻击)
n相同,但e,c不同 考察 共模攻击
上述两个密钥加密的密文c1,c2是由(n1,e1),(n2,e2)加密得到的,这个时候我们不需要计算d,可以直接解出密文m
根据RSA加密原理 我们可知:
- c1 = m^e1 % n
- c2 = m^e2 % n
若两个密钥e互素 根据扩展欧几里得算法,存在 s1、s2使得:
e1 * s1 + e2 * s2 = 1
因此,存在s1、s2 满足:
c1^s1 * c2^s2 mod n
≡ (m^e1)^s1 * (m^e2)^s2 mod n
≡ m^(e1+s1+e2+s2) mod n
≡ m mod n
因此便可不需要d 利用 c1 c2 e1 e2求解明文m 这就是共模攻击的原理
poc如下:
import gmpy2
from Crypto.Util.number import *
e1 = 797
e2 = 521
c1 = 11157593264920825445770016357141996124368529899750745256684450189070288181107423044846165593218013465053839661401595417236657920874113839974471883493099846397002721270590059414981101686668721548330630468951353910564696445509556956955232059386625725883038103399028010566732074011325543650672982884236951904410141077728929261477083689095161596979213961494716637502980358298944316636829309169794324394742285175377601826473276006795072518510850734941703194417926566446980262512429590253643561098275852970461913026108090608491507300365391639081555316166526932233787566053827355349022396563769697278239577184503627244170930
c2 = 6699274351853330023117840396450375948797682409595670560999898826038378040157859939888021861338431350172193961054314487476965030228381372659733197551597730394275360811462401853988404006922710039053586471244376282019487691307865741621991977539073601368892834227191286663809236586729196876277005838495318639365575638989137572792843310915220039476722684554553337116930323671829220528562573169295901496437858327730504992799753724465760161805820723578087668737581704682158991028502143744445435775458296907671407184921683317371216729214056381292474141668027801600327187443375858394577015394108813273774641427184411887546849
n = 15944475431088053285580229796309956066521520107276817969079550919586650535459242543036143360865780730044733026945488511390818947440767542658956272380389388112372084760689777141392370253850735307578445988289714647332867935525010482197724228457592150184979819463711753058569520651205113690397003146105972408452854948512223702957303406577348717348753106868356995616116867724764276234391678899662774272419841876652126127684683752880568407605083606688884120054963974930757275913447908185712204577194274834368323239143008887554264746068337709465319106886618643849961551092377843184067217615903229068010117272834602469293571
_, s1, s2 = gmpy2.gcdext(e1,e2)
m = pow(c1,s1,n)*pow(c2,s2,n) %n
print(long_to_bytes(m))
# b'flag{sh4r3_N}'
easyrsa4(小明文攻击)
小明文攻击是基于低加密指数的
这道题给了 e、n、c
e = 3
n = 18970053728616609366458286067731288749022264959158403758357985915393383117963693827568809925770679353765624810804904382278845526498981422346319417938434861558291366738542079165169736232558687821709937346503480756281489775859439254614472425017554051177725143068122185961552670646275229009531528678548251873421076691650827507829859299300272683223959267661288601619845954466365134077547699819734465321345758416957265682175864227273506250707311775797983409090702086309946790711995796789417222274776215167450093735639202974148778183667502150202265175471213833685988445568819612085268917780718945472573765365588163945754761
c = 150409620528139732054476072280993764527079006992643377862720337847060335153837950368208902491767027770946661
但是 e=3 非常小 而且根据c和n位数的比对 明文过小,导致明文的e次方仍然小于n
这种情况直接对密文e次开方,即可得到明文
import gmpy2
from Crypto.Util.number import *
e = 3
c = 150409620528139732054476072280993764527079006992643377862720337847060335153837950368208902491767027770946661
m = gmpy2.iroot(c,3)[0]
print(long_to_bytes(m))
# b'flag{Sm4ll_eee}'
也可以通过 爆破 m^e = c + k*n 去爆破k 开根求m
★ easyrsa5(低解密指数攻击-维纳攻击)
主要利用的是私钥d很小,表现形式一般是e很大
e = 284100478693161642327695712452505468891794410301906465434604643365855064101922252698327584524956955373553355814138784402605517536436009073372339264422522610010012877243630454889127160056358637599704871937659443985644871453345576728414422489075791739731547285138648307770775155312545928721094602949588237119345
n = 468459887279781789188886188573017406548524570309663876064881031936564733341508945283407498306248145591559137207097347130203582813352382018491852922849186827279111555223982032271701972642438224730082216672110316142528108239708171781850491578433309964093293907697072741538649347894863899103340030347858867705231
c = 350429162418561525458539070186062788413426454598897326594935655762503536409897624028778814302849485850451243934994919418665502401195173255808119461832488053305530748068788500746791135053620550583421369214031040191188956888321397450005528879987036183922578645840167009612661903399312419253694928377398939392827
利用github上开源 攻击代码:
GitHub - pablocelayes/rsa-wiener-attack: A Python implementation of the Wiener attack on RSA public-key encryption scheme.
攻击代码逻辑项目已经写好 我们编写exp.py
import gmpy2
import RSAwienerHacker
from Crypto.Util.number import *
e = int(input("Input e:"))
n = int(input("Input n:"))
c = int(input("Input c:"))
d = RSAwienerHacker.hack_RSA(e,n)
m = gmpy2.powmod(c,d,n)
print("d:",d)
print(long_to_bytes(m))
easyrsa6(pq相似)
题目下载下来一个附件,得到:
import gmpy2,libnum
from Crypto.Util.number import getPrime
from secret import flag
e = 0x10001
p = getPrime(1024)
q = gmpy2.next_prime(p)
n = p * q
print("n =",n)
m = libnum.s2n(flag)
c = pow(m,e,n)
print("c =", c)
# n = 26737417831000820542131903300607349805884383394154602685589253691058592906354935906805134188533804962897170211026684453428204518730064406526279112572388086653330354347467824800159214965211971007509161988095657918569122896402683130342348264873834798355125176339737540844380018932257326719850776549178097196650971801959829891897782953799819540258181186971887122329746532348310216818846497644520553218363336194855498009339838369114649453618101321999347367800581959933596734457081762378746706371599215668686459906553007018812297658015353803626409606707460210905216362646940355737679889912399014237502529373804288304270563
# c = 18343406988553647441155363755415469675162952205929092244387144604220598930987120971635625205531679665588524624774972379282080365368504475385813836796957675346369136362299791881988434459126442243685599469468046961707420163849755187402196540739689823324440860766040276525600017446640429559755587590377841083082073283783044180553080312093936655426279610008234238497453986740658015049273023492032325305925499263982266317509342604959809805578180715819784421086649380350482836529047761222588878122181300629226379468397199620669975860711741390226214613560571952382040172091951384219283820044879575505273602318856695503917257
题目 p、q生成方式为
p = getPrime(1024)
q = gmpy2.next_prime(p)
p q相差太小 所以 n=p*q ≈p²
import gmpy2
from Crypto.Util.number import *
e = 0x10001
n = 26737417831000820542131903300607349805884383394154602685589253691058592906354935906805134188533804962897170211026684453428204518730064406526279112572388086653330354347467824800159214965211971007509161988095657918569122896402683130342348264873834798355125176339737540844380018932257326719850776549178097196650971801959829891897782953799819540258181186971887122329746532348310216818846497644520553218363336194855498009339838369114649453618101321999347367800581959933596734457081762378746706371599215668686459906553007018812297658015353803626409606707460210905216362646940355737679889912399014237502529373804288304270563
c = 18343406988553647441155363755415469675162952205929092244387144604220598930987120971635625205531679665588524624774972379282080365368504475385813836796957675346369136362299791881988434459126442243685599469468046961707420163849755187402196540739689823324440860766040276525600017446640429559755587590377841083082073283783044180553080312093936655426279610008234238497453986740658015049273023492032325305925499263982266317509342604959809805578180715819784421086649380350482836529047761222588878122181300629226379468397199620669975860711741390226214613560571952382040172091951384219283820044879575505273602318856695503917257
p = gmpy2.next_prime(gmpy2.iroot(n,2)[0])
q = n//p
phi_n = (p-1)*(q-1)
d = gmpy2.invert(e,phi_n)
m = pow(c,d,n)
print(long_to_bytes(m))
PS:这道题实际上 n也可以放到 factordb.com 分解 直接得到了 p、q
★ easyrsa7(CopperSmith攻击 低位数据缺失-知p高位)
e = 0x10001
p>>128<<128 = 0xd1c520d9798f811e87f4ff406941958bab8fc24b19a32c3ad89b0b73258ed3541e9ca696fd98ce15255264c39ae8c6e8db5ee89993fa44459410d30a0a8af700ae3aee8a9a1d6094f8c757d3b79a8d1147e85be34fb260a970a52826c0a92b46cefb5dfaf2b5a31edf867f8d34d2222900000000000000000000000000000000
n = 0x79e0bf9b916e59286163a1006f8cefd4c1b080387a6ddb98a3f3984569a4ebb48b22ac36dff7c98e4ebb90ffdd9c07f53a20946f57634fb01f4489fcfc8e402865e152820f3e2989d4f0b5ef1fb366f212e238881ea1da017f754d7840fc38236edba144674464b661d36cdaf52d1e5e7c3c21770c5461a7c1bc2db712a61d992ebc407738fc095cd8b6b64e7e532187b11bf78a8d3ddf52da6f6a67c7e88bef5563cac1e5ce115f3282d5ff9db02278859f63049d1b934d918f46353fea1651d96b2ddd874ec8f1e4b9d487d8849896d1c21fb64029f0d6f47e560555b009b96bfd558228929a6cdf3fb6d47a956829fb1e638fcc1bdfad4ec2c3590dea1ed3
c = 0x1b2b4f9afed5fb5f9876757e959c183c2381ca73514b1918d2f123e386bebe9832835350f17ac439ac570c9b2738f924ef49afea02922981fad702012d69ea3a3c7d1fc8efc80e541ca2622d7741090b9ccd590906ac273ffcc66a7b8c0d48b7d62d6cd6dd4cd75747c55aac28f8be3249eb255d8750482ebf492692121ab4b27b275a0f69b15baef20bf812f3cbf581786128b51694331be76f80d6fb1314d8b280eaa16c767821b9c2ba05dfde5451feef22ac3cb3dfbc88bc1501765506f0c05045184292a75c475486b680f726f44ef8ddfe3c48f75bb03c8d44198ac70e6b7c885f53000654db22c8cee8eb4f65eaeea2da13887aaf53d8c254d2945691
>> 和 <<都是位运算,对二进制数进行移位操作
>> 1 右移一位 相当于 /2
这里 “p>>128<<128" p右移128位再左移128位 之后 p末尾很多0,p低位数据缺失
p,q二进制位数相同时 β一般只能取 0.4
详细讲解可以看:RSA中coppersmith定理的应用条件_small_roots_M3ng@L的博客-CSDN博客
利用 sagemath 去恢复p
import gmpy2
from Crypto.Util.number import *
e = 0x10001
p = 0xd1c520d9798f811e87f4ff406941958bab8fc24b19a32c3ad89b0b73258ed3541e9ca696fd98ce15255264c39ae8c6e8db5ee89993fa44459410d30a0a8af700ae3aee8a9a1d6094f8c757d3b79a8d1147e85be34fb260a970a52826c0a92b46cefb5dfaf2b5a31edf867f8d34d2222900000000000000000000000000000000
n = 0x79e0bf9b916e59286163a1006f8cefd4c1b080387a6ddb98a3f3984569a4ebb48b22ac36dff7c98e4ebb90ffdd9c07f53a20946f57634fb01f4489fcfc8e402865e152820f3e2989d4f0b5ef1fb366f212e238881ea1da017f754d7840fc38236edba144674464b661d36cdaf52d1e5e7c3c21770c5461a7c1bc2db712a61d992ebc407738fc095cd8b6b64e7e532187b11bf78a8d3ddf52da6f6a67c7e88bef5563cac1e5ce115f3282d5ff9db02278859f63049d1b934d918f46353fea1651d96b2ddd874ec8f1e4b9d487d8849896d1c21fb64029f0d6f47e560555b009b96bfd558228929a6cdf3fb6d47a956829fb1e638fcc1bdfad4ec2c3590dea1ed3
c = 0x1b2b4f9afed5fb5f9876757e959c183c2381ca73514b1918d2f123e386bebe9832835350f17ac439ac570c9b2738f924ef49afea02922981fad702012d69ea3a3c7d1fc8efc80e541ca2622d7741090b9ccd590906ac273ffcc66a7b8c0d48b7d62d6cd6dd4cd75747c55aac28f8be3249eb255d8750482ebf492692121ab4b27b275a0f69b15baef20bf812f3cbf581786128b51694331be76f80d6fb1314d8b280eaa16c767821b9c2ba05dfde5451feef22ac3cb3dfbc88bc1501765506f0c05045184292a75c475486b680f726f44ef8ddfe3c48f75bb03c8d44198ac70e6b7c885f53000654db22c8cee8eb4f65eaeea2da13887aaf53d8c254d2945691
pbits = 1024
kbits = 128
PR.<x> = PolynomialRing(Zmod(n))
f = x + p
roots = f.small_roots(X=2^kbits, beta=0.4)
if roots:
p = p+int(roots[0])
print("p = "+str(p))
q = n//p
phi_n = (p-1)*(q-1)
d = gmpy2.invert(e,phi_n)
m = gmpy2.powmod(c,d,n)
print(long_to_bytes(m))
easyrsa8(公钥解析)
给了 public.key 和 flag.enc
SSL在线工具-公钥解析
去网站上 解析一下 得到 e和n
利用在线网站 对n进行因数分解 得到 p、q
密文为flag.enc文件内容
解密脚本如下:
import gmpy2
from Crypto.Cipher import PKCS1_OAEP
#PKCS1 OAEP 是一种基于 RSA 和 OAEP 填充的非对称密码
from Crypto.PublicKey import RSA
e = 65537
n = 10306247299477991196335954707897189353577589618180446614762218980226685668311143526740800444344046158260556585833057716406703213966249956775927205061731821632025483608182881492214855240841820024816859031176291364212054293818204399157346955465232586109199762630150640804366966946066155685218609638749171632685073
p = 106249972159566919549855203174197828387397831115262336234662051342543151219702510584956705611794290291345944183845955839244363030579896461607496959399297130227066841321473005074379950936513608503266587950271044991876848389878395867601515004796212227929894460104645781488319246866661398816686697306692491058609
q = n//p
phi_n = (p-1)*(q-1)
d = int(gmpy2.invert(e,phi_n))
rsakey = RSA.importKey(open(r'C:\Users\lenovo\Desktop\normal_rsa\easyrsa8\public.key', 'r').read())
privatekey = RSA.construct((n,e,d,p,q))
rsa = PKCS1_OAEP.new(privatekey)
m = rsa.decrypt(open(r'C:\Users\lenovo\Desktop\normal_rsa\easyrsa8\flag.enc', 'rb').read())
print(m)
★ funnyrsa1(e和phi不互素)
题目给了 e1、p1、q1、c1 和 e2、p2、q2、c2
e1 = 14606334023791426
p1 = 121009772735460235364940622989433807619211926015494087453674747614331295040063679722422298286549493698150690694965106103822315378461970129912436074962111424616439032849788953648286506433464358834178903821069564798378666159882090757625817745990230736982709059859613843100974349380542982235135982530318438330859
q1 = 130968576816900149996914427770826228884925960001279609559095138835900329492765336419489982304805369724685145941218640504262821549441728192761733409684831633194346504685627189375724517070780334885673563409259345291959439026700006694655545512308390416859315892447092639503318475587220630455745460309886030186593
c1 = 11402389955595766056824801105373550411371729054679429421548608725777586555536302409478824585455648944737304660137306241012321255955693234304201530700362069004620531537922710568821152217381257446478619320278993539785699090234418603086426252498046106436360959622415398647198014716351359752734123844386459925553497427680448633869522591650121047156082228109421246662020164222925272078687550896012363926358633323439494967417041681357707006545728719651494384317497942177993032739778398001952201667284323691607312819796036779374423837576479275454953999865750584684592993292347483309178232523897058253412878901324740104919248
e2 = 13813369129257838
p2 = 121009772735460235364940622989433807619211926015494087453674747614331295040063679722422298286549493698150690694965106103822315378461970129912436074962111424616439032849788953648286506433464358834178903821069564798378666159882090757625817745990230736982709059859613843100974349380542982235135982530318438330859
q2 = 94582257784130735233174402362819395926641026753071039760251190444144495369829487705195913337502962816079184062352678128843179586054535283861793827497892600954650126991213176547276006780610945133603745974181504975165082485845571788686928859549252522952174376071500707863379238688200493621993937563296490615649
c2 = 7984888899827615209197324489527982755561403577403539988687419233579203660429542197972867526015619223510964699107198708420785278262082902359114040327940253582108364104049849773108799812000586446829979564395322118616382603675257162995702363051699403525169767736410365076696890117813211614468971386159587698853722658492385717150691206731593509168262529568464496911821756352254486299361607604338523750318977620039669792468240086472218586697386948479265417452517073901655900118259488507311321060895347770921790483894095085039802955700146474474606794444308825840221205073230671387989412399673375520605000270180367035526919
根据题目可知 p1=p2 m相同而且 n1、n2、c1、c2不同
但是求m的话发现 两个e和其对应的phi求不出来模逆 e和phi也不互素
但关键是这道题有两个不同的c,给定两个密文的情况下,通常需要找到两者之间存在的关系,“合并”密文求解才能得到正确的明文
求 gcd(e1,phi_n) = 14
由于m^e mod n =c,m一样,e不同,c才不同。改变了e,对应的密文c也需要改变
我们把 m^14看成一个整体 M 则 M^x ≡ c mod n 那么 M的加密指数E 就是 e//x 解密指数D就变成了 invert(e//x,phi) 从而我们就可以根据 c^D = M mod n 求解出来M 即 m^x 对M开x次方根即可得到m
但根据第一段已知条件就能把m求出来吗?显然是不可能的。两段已知条件中p1和p2是相等的,但是q1和q2不相等,所以p1*q1!=p2*q2,也就是说两端条件下m所在的有限域不同,第一段条件直接开根解出来的明文m不一定满足第二段的域
不可以直接利用一段已知 e、p、q、c求出来m
那我们把两段已知条件列出来:
此时有:
- m1^14 = c1 mod p*q1
- m2^14 = c2 mod p*q2
根据同余的性质:
则 且
则有:
- m1^14 = c1 mod q1
- m2^14 = c2 mod q2
根据中国剩余定理 结合c1、c2 求出特解c
求特解c的代码如下:
import libsum
res = libsum.solve_crt([c1, c2], [q1, q2])
得到一个新的密文c,这里的e依旧是14,n=q1*q2
m^14 = c mod q1*q2 这里依旧不能直接开方求
此时 14 与 phi_n 也不互素 gcd(e,phi_n)=2
因此 把 (m^2)^7 = c mod q1*q2 这里把 m^2看成整体,求D = invert(7,(q1-1)*(q2-1)) 之后rsa 根据 c^D = M mod n
得到 m^2 开二次根得到明文m
import gmpy2
import libnum
from Crypto.Util.number import *
e1 = 14606334023791426
p1 = 121009772735460235364940622989433807619211926015494087453674747614331295040063679722422298286549493698150690694965106103822315378461970129912436074962111424616439032849788953648286506433464358834178903821069564798378666159882090757625817745990230736982709059859613843100974349380542982235135982530318438330859
q1 = 130968576816900149996914427770826228884925960001279609559095138835900329492765336419489982304805369724685145941218640504262821549441728192761733409684831633194346504685627189375724517070780334885673563409259345291959439026700006694655545512308390416859315892447092639503318475587220630455745460309886030186593
c1 = 11402389955595766056824801105373550411371729054679429421548608725777586555536302409478824585455648944737304660137306241012321255955693234304201530700362069004620531537922710568821152217381257446478619320278993539785699090234418603086426252498046106436360959622415398647198014716351359752734123844386459925553497427680448633869522591650121047156082228109421246662020164222925272078687550896012363926358633323439494967417041681357707006545728719651494384317497942177993032739778398001952201667284323691607312819796036779374423837576479275454953999865750584684592993292347483309178232523897058253412878901324740104919248
n1 = p1*q1
e2 = 13813369129257838
p2 = 121009772735460235364940622989433807619211926015494087453674747614331295040063679722422298286549493698150690694965106103822315378461970129912436074962111424616439032849788953648286506433464358834178903821069564798378666159882090757625817745990230736982709059859613843100974349380542982235135982530318438330859
q2 = 94582257784130735233174402362819395926641026753071039760251190444144495369829487705195913337502962816079184062352678128843179586054535283861793827497892600954650126991213176547276006780610945133603745974181504975165082485845571788686928859549252522952174376071500707863379238688200493621993937563296490615649
c2 = 7984888899827615209197324489527982755561403577403539988687419233579203660429542197972867526015619223510964699107198708420785278262082902359114040327940253582108364104049849773108799812000586446829979564395322118616382603675257162995702363051699403525169767736410365076696890117813211614468971386159587698853722658492385717150691206731593509168262529568464496911821756352254486299361607604338523750318977620039669792468240086472218586697386948479265417452517073901655900118259488507311321060895347770921790483894095085039802955700146474474606794444308825840221205073230671387989412399673375520605000270180367035526919
n2 = p2*q2
phi_n1 = (p1-1)*(q1-1)
phi_n2 = (p2-1)*(q2-1)
x1 = gmpy2.gcd(e1,phi_n1) # 14
x2 = gmpy2.gcd(e2,phi_n1) # 14
e1_14 = e1//x1
e2_14 = e2//x2
d1_14 = gmpy2.invert(e1_14,phi_n1)
d2_14 = gmpy2.invert(e2_14,phi_n2)
m1_14 = pow(c1,d1_14,n1)
m2_14 = pow(c2,d2_14,n2)
# libnum.solve_crt 专门求解中国剩余定理特解
c = libnum.solve_crt([m1_14,m2_14],[q1,q2])
n = q1 * q2
phi_n = (q1 - 1) * (q2 - 1)
e = 14
x = gmpy2.gcd(e,phi_n) # 2
E = e//x
d = gmpy2.invert(E,phi_n)
m_2 = pow(c,d,n)
m = gmpy2.iroot(m_2,2)[0]
print(long_to_bytes(m))
# b"flag{gcd_e&\xcf\x86_isn't_1}"
https://www.cnblogs.com/nLesxw/p/rsa_funnyrsa1.html
funnyrsa2(n多素数因子分解)
e = 0x10001
p = getPrime(80)
q = getPrime(80)
r = getPrime(80)
n = p * q * r
n 由三个素数因子p、q、r 组成 但是n比较小 在线网站分解得到 p、q、r
只是 phi_n = (p-1)*(q-1)*(r-1) 其他的都一样,正常解就行
import gmpy2
from Crypto.Util.number import *
e = 0x10001
n = 897607935780955837078784515115186203180822213482989041398073067996023639
c = 490571531583321382715358426750276448536961994273309958885670149895389968
p = 876391552113414716726089
q = 932470255754103340237147
r = 1098382268985762240184333
phi_n = (p-1)*(q-1)*(r-1)
d = gmpy2.invert(e,phi_n)
m = pow(c,d,n)
# b'flag{what_that_fvck_r}'
funnyrsa3(dp泄露)
题目给了 e、n、dp、c 考点:dp 泄露
e = 65537
n = 13851998696110232034312408768370264747862778787235362033287301947690834384177869107768578977872169953363148442670412868565346964490724532894099772144625540138618913694240688555684873934424471837897053658485573395777349902581306875149677867098014969597240339327588421766510008083189109825385296069501377605893298996953970043168244444585264894721914216744153344106498382558756181912535774309211692338879110643793628550244212618635476290699881188640645260075209594318725693972840846967120418641315829098807385382509029722923894508557890331485536938749583463709142484622852210528766911899504093351926912519458381934550361
dp = 100611735902103791101540576986246738909129436434351921338402204616138072968334504710528544150282236463859239501881283845616704984276951309172293190252510177093383836388627040387414351112878231476909883325883401542820439430154583554163420769232994455628864269732485342860663552714235811175102557578574454173473
c = 6181444980714386809771037400474840421684417066099228619603249443862056564342775884427843519992558503521271217237572084931179577274213056759651748072521423406391343404390036640425926587772914253834826777952428924120724879097154106281898045222573790203042535146780386650453819006195025203611969467741808115336980555931965932953399428393416196507391201647015490298928857521725626891994892890499900822051002774649242597456942480104711177604984775375394980504583557491508969320498603227402590571065045541654263605281038512927133012338467311855856106905424708532806690350246294477230699496179884682385040569548652234893413
原理:
什么是dp? dp 就是 d mod p-1
因为 e*d ≡ 1 mod φ(n) => e*d ≡ 1 mod (p-1) => e*dp ≡ 1 mod (p-1) => e*dp = k*(p-1) + 1
已知e,dp 可以通过爆破 k 得到 (p-1) 进而求得 p
而 c^dp = m^(e*dp) = m^(k*(p-1) + 1) ≡ m mod p 费马小定理
所以可以通过 c 和dp来求m
from Crypto.Util.number import *
e = 65537
n = 13851998696110232034312408768370264747862778787235362033287301947690834384177869107768578977872169953363148442670412868565346964490724532894099772144625540138618913694240688555684873934424471837897053658485573395777349902581306875149677867098014969597240339327588421766510008083189109825385296069501377605893298996953970043168244444585264894721914216744153344106498382558756181912535774309211692338879110643793628550244212618635476290699881188640645260075209594318725693972840846967120418641315829098807385382509029722923894508557890331485536938749583463709142484622852210528766911899504093351926912519458381934550361
dp = 100611735902103791101540576986246738909129436434351921338402204616138072968334504710528544150282236463859239501881283845616704984276951309172293190252510177093383836388627040387414351112878231476909883325883401542820439430154583554163420769232994455628864269732485342860663552714235811175102557578574454173473
c = 6181444980714386809771037400474840421684417066099228619603249443862056564342775884427843519992558503521271217237572084931179577274213056759651748072521423406391343404390036640425926587772914253834826777952428924120724879097154106281898045222573790203042535146780386650453819006195025203611969467741808115336980555931965932953399428393416196507391201647015490298928857521725626891994892890499900822051002774649242597456942480104711177604984775375394980504583557491508969320498603227402590571065045541654263605281038512927133012338467311855856106905424708532806690350246294477230699496179884682385040569548652234893413
temp = e*dp # k*(p-1) + 1
k=0
while True:
k+=1
if (temp-1)%k==0:
x = (temp-1)//k + 1
if n%x==0:
p = (temp-1)//k +1
break
m = pow(c,dp,p)
print(long_to_bytes(m))
# b'flag{dp_i5_1eak}'
★ unusualrsa1(CopperSmith攻击 低位数据缺失-知m高位)
考点与 easyrsa7类似 低位数据缺失
from Crypto.Util.number import getPrime,bytes_to_long,long_to_bytes
from random import randint
from secret import flag
p = getPrime(1024)
q = getPrime(1024)
n = p*q
print(n)
m = bytes_to_long(long_to_bytes(randint(0,30))*208+flag)
assert(m.bit_length()==2044)
print((m>>315)<<315)
c = pow(m,3,n)
print(c)
#14113948189208713011909396304970377626324044633561155020366406284451614054260708934598840781397326960921718892801653205159753091559901114082556464576477585198060530094478860626532455065960136263963965819002575418616768412539016154873800614138683106056209070597212668250136909436974469812231498651367459717175769611385545792201291192023843434476550550829737236225181770896867698281325858412643953550465132756142888893550007041167700300621499970661661288422834479368072744930285128061160879720771910458653611076539210357701565156322144818787619821653007453741709031635862923191561438148729294430924288173571196757351837
#1520800285708753284739523608878585974609134243280728660335545667177630830064371336150456537012842986526527904043383436211487979254140749228004148347597566264500276581990635110200009305900689510908049771218073767918907869112593870878204145615928290375086195098919355531430003571366638390993296583488184959318678321571278510231561645872308920917404996519309473979203661442792048291421574603018835698487725981963573816645574675640357569465990665689618997534740389987351864738104038598104713275375385003471306823348792559733332094774873827383320058176803218213042061965933143968710199376164960850951030741280074168795136
#6635663565033382363211849843446648120305449056573116171933923595209656581213410699649926913276685818674688954045817246263487415328838542489103709103428412175252447323358040041217431171817865818374522191881448865227314554997131690963910348820833080760482835650538394814181656599175839964284713498394589419605748581347163389157651739759144560719049281761889094518791244702056048080280278984031050608249265997808217512349309696532160108250480622956599732443714546043439089844571655280770141647694859907985919056009576606333143546094941635324929407538860140272562570973340199814409134962729885962133342668270226853146819
m>>315 << 315 可知 m低位缺失的位数为 315
利用 sagemath 去恢复m
题目给了 m高位、n、c、e=3 ,可知 c ≡ m^3 mod n
将同余式项全部移到一边 0 ≡ m^3 - c mod n
已知 n、c 求解 m
from Crypto.Util.number import *
e = 3
n = 14113948189208713011909396304970377626324044633561155020366406284451614054260708934598840781397326960921718892801653205159753091559901114082556464576477585198060530094478860626532455065960136263963965819002575418616768412539016154873800614138683106056209070597212668250136909436974469812231498651367459717175769611385545792201291192023843434476550550829737236225181770896867698281325858412643953550465132756142888893550007041167700300621499970661661288422834479368072744930285128061160879720771910458653611076539210357701565156322144818787619821653007453741709031635862923191561438148729294430924288173571196757351837
c = 6635663565033382363211849843446648120305449056573116171933923595209656581213410699649926913276685818674688954045817246263487415328838542489103709103428412175252447323358040041217431171817865818374522191881448865227314554997131690963910348820833080760482835650538394814181656599175839964284713498394589419605748581347163389157651739759144560719049281761889094518791244702056048080280278984031050608249265997808217512349309696532160108250480622956599732443714546043439089844571655280770141647694859907985919056009576606333143546094941635324929407538860140272562570973340199814409134962729885962133342668270226853146819
m_high = 1520800285708753284739523608878585974609134243280728660335545667177630830064371336150456537012842986526527904043383436211487979254140749228004148347597566264500276581990635110200009305900689510908049771218073767918907869112593870878204145615928290375086195098919355531430003571366638390993296583488184959318678321571278510231561645872308920917404996519309473979203661442792048291421574603018835698487725981963573816645574675640357569465990665689618997534740389987351864738104038598104713275375385003471306823348792559733332094774873827383320058176803218213042061965933143968710199376164960850951030741280074168795136
pbits = 2044
kbits = 315
R.<x> = PolynomialRing(Zmod(n))
f = (m_high + x)^e - c
m_low = f.small_roots(2^kbits,0.4)[0]
m = int(m_high + m_low)
print("m =",m)
print(long_to_bytes(m))
★ unusualrsa2(Related Message Attack 同[n,e]加密线性变换后的m)
下载 附件得到:
from Crypto.Util.number import getPrime,bytes_to_long,long_to_bytes
from functools import reduce
from secret import flag, x, y
m = bytes_to_long(flag)
p = getPrime(1024)
q = getPrime(1024)
n = p*q
print(n)
assert(reduce(lambda x,y:x&y,[(i-5)*i+6==0 for i in x]))
assert(reduce(lambda x,y:x&y,[(j-15)*j+44==0 for j in y]))
print(pow(reduce(lambda x,y:x*m+y,x),17,n))
print(pow(reduce(lambda x,y:x*m+y,y),17,n))
#23772599983135215481563178266884362291876571759991288577057472733374903836591330410574958472090396886895304944176208711481780781286891334062794555288959410390926474473859289842654809538435377431088422352076225067494924657598298955407771484146155998883073439266427190212827600119365643065276814044272790573450938596830336430371987561905132579730619341196199420897034988685012777895002554746080384319298123154671447844799088258541911028041717897434816921424155687677867019535399434825468160227242441375503664915265223696139025407768146464383537556265875013085702422829200814612395116961538432886116917063119749068212699
#10900151504654409767059699202929100225155892269473271859207513720755903691031362539478242920144073599515746938827937863835169270383721094542639011665235593065932998091574636525973099426040452626893461449084383663453549354608769727777329036059746386523843912382289597182615339786437186169811342356085836838520978047561127661777189045888648773949147220411427306098338616422692914110656004863767719312410906124366000507952960331116878197129010412361636679449281808407214524741732730279777729251515759320442591663641984363061618865267606007355576230009922421807527598213455112981354590909603317525854070358390622096569841
#17298679220717326374674940612143058330715465693318467692839033642321129433471254547497087746971317567301086124779289015934582615377165560688447452762043163082394944604062014490446763247008217251611443338103074143809936437694543761369945095202092750900940979469994907399829695696313513303922266742415376818434932335640062684245008822643258497589196668426788916969378417960200705779461808292296450298558001909603602502604228973101048082095642290047196235959438278631661658312398313171590515776453711432353011579809351076532129444735206408591345372296372378396539831385036814349328459266432393612919118094115543053115450
题目给了 n、c1、c2以及x和y的条件
这里 用到了lambda表达式 和 reduce函数,
lambda
表达式是一行的函数。它们在其他语言中也被称为匿名函数 同时 lambda
表达式返回的是function类型,说明是一个函数类型
lambda语句中,冒号前是参数,可以有多个,用逗号隔开,冒号右边的返回值
我们再来看看reduce 函数
reduce函数原本在python2中也是个内置函数,不过在python3中被移到functools模块中。
reduce(function, iterable[, initializer])
reduce()函数参数:
- function – 函数,有两个参数
- iterable – 可迭代对象
- initializer – 可选,初始参数
功能:reduce函数先从列表(或序列)中取出2个元素执行指定函数,并将输出结果与第3个元素传入函数执行,输出结果再与第4个元素传入函数执行,…,以此类推,直到列表每个元素都取完
返回:返回函数运算结果
例如 : 求列表元素累加和
def add(x, y) : # 两数相加
return x + y
sum1 = reduce(add, [1,2,3,4,5]) # 计算列表和:1+2+3+4+5
sum2 = reduce(lambda x, y: x+y, [1,2,3,4,5]) # 使用 lambda 匿名函数
print(sum1) #15
print(sum2) #15
那么回到题目:
assert(reduce(lambda x,y:x&y,[(i-5)*i+6==0 for i in x]))
assert(reduce(lambda x,y:x&y,[(j-15)*j+44==0 for j in y]))
print(pow(reduce(lambda x,y:x*m+y,x),17,n))
print(pow(reduce(lambda x,y:x*m+y,y),17,n))
lambda x,y:x&y 定义的匿名函数返回值为bool类型,要满足 x且y,而函数参数传入的是 列表里表达式的值
因此 求出来 满足 (i-5)*i+6=0 的解 i1,i2 即 x=[i1,i2] assert就不会报错 y 同理
最终解出来:x=[2,3] y=[4,11]
因此
- reduce(lambda x,y:x*m+y,x) = 2m+3
- reduce(lambda x,y:x*m+y,y) = 4m+11
因此题目用相同的公钥[e, n]去加密分别用x和y做线性变换后的m
得到的c1、c2如下:
- c1 = (2m+3)^17 mod n
- c2 = (4m+11)^17 mod n
典型的Related Message Attack
在其他师傅那边看到的这类题型的sage解密脚本
解密脚本如下:
import binascii
def attack(c1, c2, n, e):
PR.<x>=PolynomialRing(Zmod(n))
# replace a,b,c,d
g1 = (2*x+3)^e - c1
g2 = (4*x+11)^e - c2
def gcd(g1, g2):
while g2:
g1, g2 = g2, g1 % g2
return g1.monic()
return -gcd(g1, g2)[0]
c1 = 10900151504654409767059699202929100225155892269473271859207513720755903691031362539478242920144073599515746938827937863835169270383721094542639011665235593065932998091574636525973099426040452626893461449084383663453549354608769727777329036059746386523843912382289597182615339786437186169811342356085836838520978047561127661777189045888648773949147220411427306098338616422692914110656004863767719312410906124366000507952960331116878197129010412361636679449281808407214524741732730279777729251515759320442591663641984363061618865267606007355576230009922421807527598213455112981354590909603317525854070358390622096569841
c2 = 17298679220717326374674940612143058330715465693318467692839033642321129433471254547497087746971317567301086124779289015934582615377165560688447452762043163082394944604062014490446763247008217251611443338103074143809936437694543761369945095202092750900940979469994907399829695696313513303922266742415376818434932335640062684245008822643258497589196668426788916969378417960200705779461808292296450298558001909603602502604228973101048082095642290047196235959438278631661658312398313171590515776453711432353011579809351076532129444735206408591345372296372378396539831385036814349328459266432393612919118094115543053115450
n = 23772599983135215481563178266884362291876571759991288577057472733374903836591330410574958472090396886895304944176208711481780781286891334062794555288959410390926474473859289842654809538435377431088422352076225067494924657598298955407771484146155998883073439266427190212827600119365643065276814044272790573450938596830336430371987561905132579730619341196199420897034988685012777895002554746080384319298123154671447844799088258541911028041717897434816921424155687677867019535399434825468160227242441375503664915265223696139025407768146464383537556265875013085702422829200814612395116961538432886116917063119749068212699
e = 17
m1 = attack(c1, c2, n, e)
print(binascii.unhexlify("%x" % int(m1)))
★ unusualrsa3(多项式RSA)
题目给了 p、N、e、c 其中 N和c都是多项式
不可约多项式的欧拉函数怎么求呢?
Lazzaro师傅提到:对于不可约多项式 g(x),φ(g(x)) = p^n -1。(此 p为 GF(p) 的模,此 n 为多项式最高项次数)
解释:
欧拉函数定义本身:欧拉函数就是指:对于一个正整数n,小于或等于n的正整数中与n互质的正整数个数(包括1)的个数,记作 φ ( n )
多项式的欧拉函数则类似,表示不高于 g(x) 幂级的环内所有多项式中,与 g(x) 无公因式(非1)的其他多项式的个数,所以每一个不高于 g(x) 幂级的环内多项式(除了它自己)均满足此条件
利用sage 在多项式环上分解N 得到两个最高项次数分别为128 和 127的不可约多项式
p = 2470567871
R.<x> = PolynomialRing(GF(p))#构造以p为模的,关于x的多项式
N = 1932231392*x^255 + 1432733708*x^254 + 1270867914*x^253 + 1573324635*x^252 + 2378103997*x^251 + 820889786*x^250 + 762279735*x^249 + 1378353578*x^248 + 1226179520*x^247 + 657116276*x^246 + 1264717357*x^245 + 1015587392*x^244 + 849699356*x^243 + 1509168990*x^242 + 2407367106*x^241 + 873379233*x^240 + 2391647981*x^239 + 517715639*x^238 + 828941376*x^237 + 843708018*x^236 + 1526075137*x^235 + 1499291590*x^234 + 235611028*x^233 + 19615265*x^232 + 53338886*x^231 + 434434839*x^230 + 902171938*x^229 + 516444143*x^228 + 1984443642*x^227 + 966493372*x^226 + 1166227650*x^225 + 1824442929*x^224 + 930231465*x^223 + 1664522302*x^222 + 1067203343*x^221 + 28569139*x^220 + 2327926559*x^219 + 899788156*x^218 + 296985783*x^217 + 1144578716*x^216 + 340677494*x^215 + 254306901*x^214 + 766641243*x^213 + 1882320336*x^212 + 2139903463*x^211 + 1904225023*x^210 + 475412928*x^209 + 127723603*x^208 + 2015416361*x^207 + 1500078813*x^206 + 1845826007*x^205 + 797486240*x^204 + 85924125*x^203 + 1921772796*x^202 + 1322682658*x^201 + 2372929383*x^200 + 1323964787*x^199 + 1302258424*x^198 + 271875267*x^197 + 1297768962*x^196 + 2147341770*x^195 + 1665066191*x^194 + 2342921569*x^193 + 1450622685*x^192 + 1453466049*x^191 + 1105227173*x^190 + 2357717379*x^189 + 1044263540*x^188 + 697816284*x^187 + 647124526*x^186 + 1414769298*x^185 + 657373752*x^184 + 91863906*x^183 + 1095083181*x^182 + 658171402*x^181 + 75339882*x^180 + 2216678027*x^179 + 2208320155*x^178 + 1351845267*x^177 + 1740451894*x^176 + 1302531891*x^175 + 320751753*x^174 + 1303477598*x^173 + 783321123*x^172 + 1400145206*x^171 + 1379768234*x^170 + 1191445903*x^169 + 946530449*x^168 + 2008674144*x^167 + 2247371104*x^166 + 1267042416*x^165 + 1795774455*x^164 + 1976911493*x^163 + 167037165*x^162 + 1848717750*x^161 + 573072954*x^160 + 1126046031*x^159 + 376257986*x^158 + 1001726783*x^157 + 2250967824*x^156 + 2339380314*x^155 + 571922874*x^154 + 961000788*x^153 + 306686020*x^152 + 80717392*x^151 + 2454799241*x^150 + 1005427673*x^149 + 1032257735*x^148 + 593980163*x^147 + 1656568780*x^146 + 1865541316*x^145 + 2003844061*x^144 + 1265566902*x^143 + 573548790*x^142 + 494063408*x^141 + 1722266624*x^140 + 938551278*x^139 + 2284832499*x^138 + 597191613*x^137 + 476121126*x^136 + 1237943942*x^135 + 275861976*x^134 + 1603993606*x^133 + 1895285286*x^132 + 589034062*x^131 + 713986937*x^130 + 1206118526*x^129 + 311679750*x^128 + 1989860861*x^127 + 1551409650*x^126 + 2188452501*x^125 + 1175930901*x^124 + 1991529213*x^123 + 2019090583*x^122 + 215965300*x^121 + 532432639*x^120 + 1148806816*x^119 + 493362403*x^118 + 2166920790*x^117 + 185609624*x^116 + 184370704*x^115 + 2141702861*x^114 + 223551915*x^113 + 298497455*x^112 + 722376028*x^111 + 678813029*x^110 + 915121681*x^109 + 1107871854*x^108 + 1369194845*x^107 + 328165402*x^106 + 1792110161*x^105 + 798151427*x^104 + 954952187*x^103 + 471555401*x^102 + 68969853*x^101 + 453598910*x^100 + 2458706380*x^99 + 889221741*x^98 + 320515821*x^97 + 1549538476*x^96 + 909607400*x^95 + 499973742*x^94 + 552728308*x^93 + 1538610725*x^92 + 186272117*x^91 + 862153635*x^90 + 981463824*x^89 + 2400233482*x^88 + 1742475067*x^87 + 437801940*x^86 + 1504315277*x^85 + 1756497351*x^84 + 197089583*x^83 + 2082285292*x^82 + 109369793*x^81 + 2197572728*x^80 + 107235697*x^79 + 567322310*x^78 + 1755205142*x^77 + 1089091449*x^76 + 1993836978*x^75 + 2393709429*x^74 + 170647828*x^73 + 1205814501*x^72 + 2444570340*x^71 + 328372190*x^70 + 1929704306*x^69 + 717796715*x^68 + 1057597610*x^67 + 482243092*x^66 + 277530014*x^65 + 2393168828*x^64 + 12380707*x^63 + 1108646500*x^62 + 637721571*x^61 + 604983755*x^60 + 1142068056*x^59 + 1911643955*x^58 + 1713852330*x^57 + 1757273231*x^56 + 1778819295*x^55 + 957146826*x^54 + 900005615*x^53 + 521467961*x^52 + 1255707235*x^51 + 861871574*x^50 + 397953653*x^49 + 1259753202*x^48 + 471431762*x^47 + 1245956917*x^46 + 1688297180*x^45 + 1536178591*x^44 + 1833258462*x^43 + 1369087493*x^42 + 459426544*x^41 + 418389643*x^40 + 1800239647*x^39 + 2467433889*x^38 + 477713059*x^37 + 1898813986*x^36 + 2202042708*x^35 + 894088738*x^34 + 1204601190*x^33 + 1592921228*x^32 + 2234027582*x^31 + 1308900201*x^30 + 461430959*x^29 + 718926726*x^28 + 2081988029*x^27 + 1337342428*x^26 + 2039153142*x^25 + 1364177470*x^24 + 613659517*x^23 + 853968854*x^22 + 1013582418*x^21 + 1167857934*x^20 + 2014147362*x^19 + 1083466865*x^18 + 1091690302*x^17 + 302196939*x^16 + 1946675573*x^15 + 2450124113*x^14 + 1199066291*x^13 + 401889502*x^12 + 712045611*x^11 + 1850096904*x^10 + 1808400208*x^9 + 1567687877*x^8 + 2013445952*x^7 + 2435360770*x^6 + 2414019676*x^5 + 2277377050*x^4 + 2148341337*x^3 + 1073721716*x^2 + 1045363399*x + 1809685811
c = 922927962*x^254 + 1141958714*x^253 + 295409606*x^252 + 1197491798*x^251 + 2463440866*x^250 + 1671460946*x^249 + 967543123*x^248 + 119796323*x^247 + 1172760592*x^246 + 770640267*x^245 + 1093816376*x^244 + 196379610*x^243 + 2205270506*x^242 + 459693142*x^241 + 829093322*x^240 + 816440689*x^239 + 648546871*x^238 + 1533372161*x^237 + 1349964227*x^236 + 2132166634*x^235 + 403690250*x^234 + 835793319*x^233 + 2056945807*x^232 + 480459588*x^231 + 1401028924*x^230 + 2231055325*x^229 + 1716893325*x^228 + 16299164*x^227 + 1125072063*x^226 + 1903340994*x^225 + 1372971897*x^224 + 242927971*x^223 + 711296789*x^222 + 535407256*x^221 + 976773179*x^220 + 533569974*x^219 + 501041034*x^218 + 326232105*x^217 + 2248775507*x^216 + 1010397596*x^215 + 1641864795*x^214 + 1365178317*x^213 + 1038477612*x^212 + 2201213637*x^211 + 760847531*x^210 + 2072085932*x^209 + 168159257*x^208 + 70202009*x^207 + 1193933930*x^206 + 1559162272*x^205 + 1380642174*x^204 + 1296625644*x^203 + 1338288152*x^202 + 843839510*x^201 + 460174838*x^200 + 660412151*x^199 + 716865491*x^198 + 772161222*x^197 + 924177515*x^196 + 1372790342*x^195 + 320044037*x^194 + 117027412*x^193 + 814803809*x^192 + 1175035545*x^191 + 244769161*x^190 + 2116927976*x^189 + 617780431*x^188 + 342577832*x^187 + 356586691*x^186 + 695795444*x^185 + 281750528*x^184 + 133432552*x^183 + 741747447*x^182 + 2138036298*x^181 + 524386605*x^180 + 1231287380*x^179 + 1246706891*x^178 + 69277523*x^177 + 2124927225*x^176 + 2334697345*x^175 + 1769733543*x^174 + 2248037872*x^173 + 1899902290*x^172 + 409421149*x^171 + 1223261878*x^170 + 666594221*x^169 + 1795456341*x^168 + 406003299*x^167 + 992699270*x^166 + 2201384104*x^165 + 907692883*x^164 + 1667882231*x^163 + 1414341647*x^162 + 1592159752*x^161 + 28054099*x^160 + 2184618098*x^159 + 2047102725*x^158 + 103202495*x^157 + 1803852525*x^156 + 446464179*x^155 + 909116906*x^154 + 1541693644*x^153 + 166545130*x^152 + 2283548843*x^151 + 2348768005*x^150 + 71682607*x^149 + 484339546*x^148 + 669511666*x^147 + 2110974006*x^146 + 1634563992*x^145 + 1810433926*x^144 + 2388805064*x^143 + 1200258695*x^142 + 1555191384*x^141 + 363842947*x^140 + 1105757887*x^139 + 402111289*x^138 + 361094351*x^137 + 1788238752*x^136 + 2017677334*x^135 + 1506224550*x^134 + 648916609*x^133 + 2008973424*x^132 + 2452922307*x^131 + 1446527028*x^130 + 29659632*x^129 + 627390142*x^128 + 1695661760*x^127 + 734686497*x^126 + 227059690*x^125 + 1219692361*x^124 + 635166359*x^123 + 428703291*x^122 + 2334823064*x^121 + 204888978*x^120 + 1694957361*x^119 + 94211180*x^118 + 2207723563*x^117 + 872340606*x^116 + 46197669*x^115 + 710312088*x^114 + 305132032*x^113 + 1621042631*x^112 + 2023404084*x^111 + 2169254305*x^110 + 463525650*x^109 + 2349964255*x^108 + 626689949*x^107 + 2072533779*x^106 + 177264308*x^105 + 153948342*x^104 + 1992646054*x^103 + 2379817214*x^102 + 1396334187*x^101 + 2254165812*x^100 + 1300455472*x^99 + 2396842759*x^98 + 2398953180*x^97 + 88249450*x^96 + 1726340322*x^95 + 2004986735*x^94 + 2446249940*x^93 + 520126803*x^92 + 821544954*x^91 + 1177737015*x^90 + 676286546*x^89 + 1519043368*x^88 + 224894464*x^87 + 1742023262*x^86 + 142627164*x^85 + 1427710141*x^84 + 1504189919*x^83 + 688315682*x^82 + 1397842239*x^81 + 435187331*x^80 + 433176780*x^79 + 454834357*x^78 + 1046713282*x^77 + 1208458516*x^76 + 811240741*x^75 + 151611952*x^74 + 164192249*x^73 + 353336244*x^72 + 1779538914*x^71 + 1489144873*x^70 + 213140082*x^69 + 1874778522*x^68 + 908618863*x^67 + 1058334731*x^66 + 1706255211*x^65 + 708134837*x^64 + 1382118347*x^63 + 2111915733*x^62 + 1273497300*x^61 + 368639880*x^60 + 1652005004*x^59 + 1977610754*x^58 + 1412680185*x^57 + 2312775720*x^56 + 59793381*x^55 + 1345145822*x^54 + 627534850*x^53 + 2159477761*x^52 + 10450988*x^51 + 1479007796*x^50 + 2082579205*x^49 + 1158447154*x^48 + 126359830*x^47 + 393411272*x^46 + 2343384236*x^45 + 2191577465*x^44 + 1281188680*x^43 + 230049708*x^42 + 539600199*x^41 + 1711135601*x^40 + 1659775448*x^39 + 1716176055*x^38 + 904363231*x^37 + 2385749710*x^36 + 567278351*x^35 + 404199078*x^34 + 372670353*x^33 + 1286079784*x^32 + 1744355671*x^31 + 2316856064*x^30 + 2106475476*x^29 + 614988454*x^28 + 2149964943*x^27 + 1065233185*x^26 + 188130174*x^25 + 540415659*x^24 + 1031409799*x^23 + 1067085678*x^22 + 1005161755*x^21 + 249654085*x^20 + 1816791634*x^19 + 1437500292*x^18 + 448596413*x^17 + 2397497659*x^16 + 2353732701*x^15 + 2068949189*x^14 + 1826419168*x^13 + 1265366199*x^12 + 547031306*x^11 + 1016962374*x^10 + 160089486*x^9 + 2264803979*x^8 + 1081806194*x^7 + 824215340*x^6 + 497731793*x^5 + 45017166*x^4 + 317548920*x^3 + 1391127733*x^2 + 1752881284*x + 1290424106
S.<x> = R.quotient(N)#关于x的瑞利定理
P, Q = N.factor()
print(N.factor())
P, Q = P[0], Q[0]
phi = (p ** P.degree() - 1) * (p ** Q.degree() - 1)
e = 0x10001
d = inverse_mod(e, phi)
m = pow(c,d,N)
m = "".join([chr(c) for c in m.list()])
print(m)
# flag{h4v3_y0u_533n_p0lyn0m14l_b453d_r54??}
★ unusualrsa4(考察数学原理 已知e、d、q模p逆)
题目 代码如下:
# ********************
# @Author: Lazzaro
# ********************
from Crypto.Util.number import getPrime,bytes_to_long
from gmpy2 import invert
from secret import flag
m = bytes_to_long(flag)
p = getPrime(1024)
q = getPrime(1024)
n = p*q
print(invert(q,p))
e = 0x10001
d = invert(e,(p-1)*(q-1))
print(d)
c = pow(m,e,n)
print(c)
#113350138578125471637271827037682321496361317426731366252238155037440385105997423113671392038498349668206564266165641194668802966439465128197299073392773586475372002967691512324151673246253769186679521811837698540632534357656221715752733588763108463093085549826122278822507051740839450621887847679420115044512
#27451162557471435115589774083548548295656504741540442329428952622804866596982747294930359990602468139076296433114830591568558281638895221175730257057177963017177029796952153436494826699802526267315286199047856818119832831065330607262567182123834935483241720327760312585050990828017966534872294866865933062292893033455722786996125448961180665396831710915882697366767203858387536850040283296013681157070419459208544201363726008380145444214578735817521392863391376821427153094146080055636026442795625833039248405951946367504865008639190248509000950429593990524808051779361516918410348680313371657111798761410501793645137
#619543409290228183446186073184791934402487500047968659800765382797769750763696880547221266055431306972840980865602729031475343233357485820872268765911041297456664938715949124290204230537793877747551374176167292845717246943780371146830637073310108630812389581197831196039107931968703635129091224513813241403591357678410312272233389708366642638825455844282490676862737715585788829936919637988039113463707959069907015464745700766013573282604376277598510224455044288896809217461295080140187509519005245601483583507547733673523120385089098002298314719617693895392148294399937798485146568296114338393548124451378170302291
这里 给了 e、d、c、和 q在模p下的逆元
考察数学原理
题目提示 :
Hint1:
ed=1+kφ
- 比较e与k比特位数
- 联立两式,尝试化简 (inv(q,p)·φ) mod p
Hint2:
- 费马小定理
- 对于任意 r,k1,k2,当 k2 为 k1 因子时,r mod k2≡(r mod k1) mod k2
已知 e、d、c、inv(p,q) 且p、q同bit位数
Hint1相关: (可以爆破k求得φ(n)值)
根据提示 比较e与k比特位数 e与k同长 可以爆破 k 得到φ(n) :
Hint2相关:(可以求出来不同倍数的p 取gcd即得到p)
设 则
φ(n) mod p ≡ (p-1)(q-1) mod p ≡ -(q-1) mod p
--> φ(n) = (p-1)(q-1) = n - p - q +1
--> x·φ(n) = xn - xp - xq +x mod p = -1 + x mod p
则有 x·φ(n) +1 -x = 0 mod p
即 f = x·φ(n) +1 -x = kp 所以p是f的因子(这个k和前面求得k没关系)
然后看提示2 :
- 费马小定理
- 对于任意 r,a1,a2,当 a2 为 a1 因子时,r mod a2≡(r mod a1) mod a2
这里没有给r ,我们任意给r 赋个值 又因为 p 是 f 的因子则
因此 就是 p的倍数
已知 φ(n) r可以 赋值两个不同的,
解密脚本如下:
# -*- coding: utf-8 -*-
from Crypto.Util.number import *
from gmpy2 import *
from itertools import *
q_1 = 113350138578125471637271827037682321496361317426731366252238155037440385105997423113671392038498349668206564266165641194668802966439465128197299073392773586475372002967691512324151673246253769186679521811837698540632534357656221715752733588763108463093085549826122278822507051740839450621887847679420115044512
d = 27451162557471435115589774083548548295656504741540442329428952622804866596982747294930359990602468139076296433114830591568558281638895221175730257057177963017177029796952153436494826699802526267315286199047856818119832831065330607262567182123834935483241720327760312585050990828017966534872294866865933062292893033455722786996125448961180665396831710915882697366767203858387536850040283296013681157070419459208544201363726008380145444214578735817521392863391376821427153094146080055636026442795625833039248405951946367504865008639190248509000950429593990524808051779361516918410348680313371657111798761410501793645137
c = 619543409290228183446186073184791934402487500047968659800765382797769750763696880547221266055431306972840980865602729031475343233357485820872268765911041297456664938715949124290204230537793877747551374176167292845717246943780371146830637073310108630812389581197831196039107931968703635129091224513813241403591357678410312272233389708366642638825455844282490676862737715585788829936919637988039113463707959069907015464745700766013573282604376277598510224455044288896809217461295080140187509519005245601483583507547733673523120385089098002298314719617693895392148294399937798485146568296114338393548124451378170302291
e = 0x10001
#在写脚本要明确自己需要什么,例如从数学原理中我们需要求解k和 φ ,那就去写对应的过程
for k in range(1, e):
t = e * d - 1 #hint1
if t % k == 0:
phi = t // k #这里的phi就是 φ(n)
kp = q_1 * phi - q_1 + 1
x1 = pow(3, phi, kp) - 1 #这里3和5处的数字随便取
x2 = pow(5, phi, kp) - 1
x = gcd(x1, x2)
if x.bit_length() == 1024:
p = x
q = invert(q_1, p)
n, phi = p*q, (p-1)*(q-1)
assert d == invert(e, phi)
m = pow(c, d, n)
print(long_to_bytes(m))
break
# b'flag{wh47_1f_y0u_kn0w_1nv3r7_q_p~?}'
★ unusualrsa5(e _phi不互素有限域情况)
题目给了 e、p、q、c 乍一看 挺简单 那不直接求d 套rsa就行??? no😥
这里 我们可以求出来 gcd(e,phi) = 20 = e本身 ≠ 1
e | p-1 且 e | q-1 不能用简单求个逆元那种正常做法
根据题目的hint:有限域 n-th root
这道题 难点在有限域 GF(p) 上求 e 次根
当 gcd(e,phi)较大时 使用一些高效算法 求解 p、q的e次方根(不太懂 我只会pow呜呜 高一点就只会sage)
m^e = c > n 则在有限域下开方 先计算 求出 Cp、Cq 在 c下的e次方根(有很多) 然后使用CRT遍历所有组合,check出明文
sagemath脚本如下:
from Crypto.Util.number import *
import libnum
p = 733089589724903586073820965792963746076789390539824437962807679954808310072656817423828613938510684864567664345751164944269489647964227519307980688068059059377123391499328155025962198363435968318689113750910755244276996554328840879221120846257832190569086861774466785101694608744384540722995426474322431441
q = 771182695213910447650732428220054698293987458796864628535794956332865106301119308051373568460701145677164052375651484670636989109023957702790185901445649197004100341656188532246838220216919835415376078688888076677350412398198442910825884505318258393640994788407100699355386681624118606588957344077387058721
n = 9057141637995599750120273501711128117576789048411357158233050845658505488383724832915968443730006384810721595601723748471745315354759415044859624198755098491311647992728384572103262800310263916249536898582100747311978019829291619921741682336800665277699122504431456051606407509905004993708771825443764723285750825546500765451509998514747599779552241055519485714649825416851221219747115910385536482995890893190128149999622905611239433481756073333147782531765685320972075370276543786386451560493093416152466142374684450770169257924330366774896526508005296520372463932722237001341584625279676089901419404816917142209281664709940400762785892142918132066900664643155176180059403739
c = 406314720119562590605554101860453913891646775958515375190169046313074168423687276987576196367702523895650602252851191274766072774312855212771035294337840170341052016067631007495713764510925931612800335613551752201920460877432379214684677593342046715833439574705829048358675771542989832566579493199671622475225225451781214904100440695928239014046619329247750637911015313431804069312072581674845078940868349474663382442540424342613429896445329365750444298236684237769335405534090013035238333534521759502103604033307768304224154383880727399879024077733935062478113298538634071453067782212909271392163928445051705642
e= 20
R.<x> = Zmod(p)[]
f = x ^ e - c
f = f.monic()
res1 = f.roots()
R.<x> = Zmod(q)[]
f = x ^ e - c
f = f.monic()
res2 = f.roots()
for i in res1:
for j in res2:
# 中国剩余定理
m =libnum.solve_crt([int(i[0]),int(j[0])],[p,q])
flag = long_to_bytes(m)
if flag.startswith(b'flag'):
print(flag)
# flag{r54__d34l1n6_w17h_3v3n_3 _&_f1nd1n6_n-7h_r0075~~}
参考:CTFshow供题 unusualrsa系列 | Lazzaro