绿城杯密码题 出题人是真的垃圾,出的这么简单,被全国的师傅打了不知道多少种解。不会出题可以不出,出这种垃圾题简直是在侮辱做题师傅们的智商。
warmup(50) 题目 密码签到题,给了以下脚本:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 from Crypto.Util.number import *from flag import flagassert flag[:5 ]=='flag{' str1 = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' def encode (plain_text, a, b, m ): cipher_text = '' for i in plain_text: if i in str1: addr = str1.find(i) cipher_text += str1[(a*addr+b) % m] else : cipher_text += i print (cipher_text) encode(flag,37 ,23 ,52 )
考点 就一个,一眼就能根据加密算法看出来这是affline cipher。
没什么好多说的,加解密函数
求个逆元完事。
解法一(预期解) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 from Crypto.Util.number import *cipher_text = 'aoxL{XaaHKP_tHgwpc_hN_ToXnnht}' str1 = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' def affline_decode (cipher_text, a, b, m ): plain_text = '' for i in cipher_text: if i in str1: addr = str1.find(i) plain_text += str1[(addr-b) * inverse(a,m) % m] else : plain_text += i print (plain_text) affline_decode(cipher_text,37 ,23 ,52 )
解法二 放进在线工具的仿射密码里,直接能求出flag原文。然后根据加密算法,爆破一下大小写。也是一种不错的解法。这道题和一般的仿射密码的唯一区别在于,一般仿射密码的字母为26个,不区分大小写。而这道题加了大小写的考点,最后肯定是要用到脚本的。
RSA-1 题目 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 from Crypto.Util.number import *import gmpy2from flag import flagassert flag[:5 ]==b'flag{' m = bytes_to_long(flag) p = getPrime(1024 ) q = getPrime(1024 ) n = p * q print ('n =' ,n)e = 0x10001 M = 2021 * m * 1001 * p c = pow (M,e,n) print ('c =' ,c)
考点 考了个小同余的性质。
证明过程不写了,比较简单。
解法一(预期解) 1 2 3 4 5 6 7 8 9 10 11 n = 17365231154926348364478276872558492775911760603002394353723603461898405740234715001820111548600914907617003806652492391686710256274156677887101997175692277729648456087534987616743724646598234466094779540729413583826355145277980479040157075453694250572316638348121571218759769533738721506811175866990851972838466307594226293836934116659685215775643285465895317755892754473332034234495795936183610569571016400535362762699517686781602302045048532131426035260878979892169441059467623523060569285570577199236309888155833013721997933960457784653262076135561769838704166810384309655788983073376941843467117256002645962737847 c = 6944967108815437735428941286784119403138319713455732155925055928646536962597672941805831312130689338014913452081296400272862710447207265099750401657828165836013122848656839100854719965188680097375491193249127725599660383746827031803066026497989298856420216250206035068180963797454792151191071433645946245914916732637007117085199442894495667455544517483404006536607121480678688000420422281380539368519807162175099763891988648117937777951069899975260190018995834904541447562718307433906592021226666885638877020304005614450763081337082838608414756162253825697420493509914578546951634127502393647068722995363753321912676 from Crypto.Util.number import *import gmpy2p = gmpy2.gcd(c,n) q = n//p phi = (p-1 )*(q-1 ) e = 0x10001 d = inverse(e,phi) print (long_to_bytes(pow (c,d,n)//1001 //p//2021 ))
解法二 rsatools里面竟然有函数能判断n
和c
是否有相同因子,属实给我蚌埠住了。大意了,没想到还有用工具做RSA的。放进去直接出d
了,然后有d
和n
能求出p
和q
,答案就出了。
用工具做密码是没有灵魂的。
RSA-2 题目 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 from Crypto.Util.number import *import gmpy2from flag import flagassert flag[:5 ]==b'flag{' m1 = bytes_to_long(flag[:20 ]) p = getPrime(512 ) p1 = gmpy2.next_prime(p) q = getPrime(512 ) q1 = gmpy2.next_prime(q) n1 = p*q*p1*q1 print ('n1 =' ,n1)e = 0x10001 c1 = pow (m1,e,n1) print ('c1 =' ,c1)m2 = bytes_to_long(flag[20 :]) p2 = getPrime(1024 ) q2 = getPrime(1024 ) print ('p2+q2 =' ,p2+q2)print ('p2*q2 =' ,p2*q2)n2 = p2*p2*q2*q2*q2 print ('n2 =' ,n2)c2 = pow (m2,e,n2) print ('c2 =' ,c2)
考点: 第一段
费马分解。
第二段解个方程(实际出了个离谱非预期,根本不用解,但是没有战队想到),然后欧拉函数。
解法: 这垃圾出题人刷没刷过题啊,祥云杯2020的原题都好意思拿来出。
祥云杯脚本走一下就行。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 n1 = 6348779979606280884589422188738902470575876294643492831465947360363568026280963989291591157710389629216109615274754718329987990551836115660879103234129921943824061416396264358110216047994331119920503431491509529604742468032906950984256964560405062345280120526771439940278606226153077959057882262745273394986607004406770035459301695806378598890589432538916219821477777021460189140081521779103226953544426441823244765828342973086422949017937701261348963541035128661464068769033772390320426795044617751909787914185985911277628404632533530390761257251552073493697518547350246993679844132297414094727147161169548160586911 c1 = 6201882078995455673376327652982610102807874783073703018551044780440620679217833227711395689114659144506630609087600915116940111002026241056808189658969089532597757995423694966667948250438579639890580690392400661711864264184444018345499567505424672090632235109624193289954785503512742400960515331371813467034511130432319427185134018830006918682733848618201088649690422818940385123599468595766345668931882249779415788129316594083269412221804774856038796248038700275509397599351533280014908894068141056694660319816046357462684688942519849441237878018480036145051967731081582598773076490918572392784684372694103015244826 jia = 274773146761138462708137582309097386437793891793691383033856524303010811294101933454824485010521468914846151819876043508541879637544444256520741418495479393777132830985856522008561088410862815913292288683761657919121930016956916865849261153721097671315883469348972925757078089715102032241818526925988645578778 cheng = 18514724270030962172566965941723224386374076294232652258701085781018776172843355920566035157331579524980108190739141959926523082142273672741849552475156278397131571360099018592018959785627785130126477982765210498547680367230723634424036009539347854344573537848628061468892166199866227984167843139793429682559241317072979374002912607549039431398267184818771503468116379618249319324788996321340764624593443106354104274472601170229835219638093242557547840060892527576940077162990069687019966946826210112318408269749294366586682732614372434218768720577917368726530200897558912687470088583774711767599580037663378929000217 n2 = 40588227045595304080360385041082238507044292731344465815296032905633525556943787610712651675460810768762763493579129831271018141591546207557410817432455139315527674932933085299277599173971912445226532235814580879585317211349524406424200622675880992390782025158621241499693400288031658194434641718026910652327933253877313106112861283314274635124734817398465059373562194694957841264834312640926278890386089611103714990646541470577351599526904458342660444968591197606820361364761648205241041444681145820799054413179462285509661124362074093583494932706249461954240408827087015525507173082129412234486228092002841868365895837463699200959915782767657258729794037776401995309244941171415842403617486719492483671490834562579225506831496881542530519595438932482796867853234159664409420977526102480385193101883785161080269573707156626838551506024455480650224305894501968583442346807126920740779780593650871645915149689424292912611578291912721896864772950410266629045542480009266574096080138709683466489568290569363478444349563498507530805502511051165160827192795520182720802422213364247355775222858214648603034743679187470844212529134374975737510982287957316878179964602394749601431823167982157434890459245394370728942790117156485268116758052636794417268680901420193002289035538753620555488506926366624641291881353268617130968991258983002165300186971963661666476600998389048880565199317280428349802824448329898502788492233381873026217202981921654673840142095839603360666049476100561268336225902504932800605464136192275593886736746497955270280541423593 c2 = 25591090168544821761746024178724660839590948190451329227481168576490717242294520739865602061082558759751196452117720647426598261568572440942370039702932821941366792140173428488344932203576334292648255551171274828821657097667106792872200082579319963310503721435500623146012954474613150848083425126987554594651797477741828655238243550266972216752593788734836373144363217639612492397228808215205862281278774096317615918854403992620720969173788151215489908812749179861803144937169587452008097008940710091361183942268245271154461872102813602754439939747566507116519362821255724179093051041994730856401493996771276172343313045755916751082693149885922105491818225012844519264933137622929024918619477538521533548551789739698933067212305578480416163609137189891797209277557411169643568540392303036719952140554435338851671440952865151077383220305295001632816442144022437763089133141886924265774247290306669825085862351732336395617276100374237159580759999593028756939354840677333467281632435767033150052439262501059299035212928041546259933118564251119588970009016873855478556588250138969938599988198494567241172399453741709840486953189764289118312870580993115636710724139809708256360212728127786394411676427828431569046279687481368215137561500777480380501551616577832499521295655237360184159889151837766353116185320317774645294201044772828099074917077896631909654671612557207653830344897644115936322128351494551004652981550758791285434809816872381900401440743578104582305215488888563166054568802145921399726673752722820646807494657299104190123945675647 from Crypto.Util.number import *from gmpy2 import *from z3 import *s=Solver() x=Int('x' ) y=Int('y' ) s.add(x+y==jia) s.add(x*y==cheng) assert s.check()==satp2=int (str (s.model()[x])) q2=int (str (s.model()[y])) phi = n2 * (p2-1 ) * (q2-1 ) // (p2 * q2) e = 0x10001 d = inverse(e,phi) m2=long_to_bytes(pow (c2,d,n2)) print (m2)phi1=p2-1 d = inverse(e,phi1) m = pow (c2, d, p2) print (long_to_bytes(m))def fermat_factorization (n ): factor_list = [] get_context().precision = 1024 x = int (sqrt(n)) while True : x += 1 y2 = x ** 2 - n if is_square(y2): y2 = mpz(y2) get_context().precision = 1024 y = int (sqrt(y2)) factor_list.append([x+y, x-y]) if len (factor_list) == 2 : break return factor_list ''' ''' * 复制并使用代码请注明引用出处哦~ * Lazzaro @ https://lazzzaro.github.io ''' ''' tmp1=(fermat_factorization(n1)[0 ])[0 ] tmp2=(fermat_factorization(n1)[0 ])[1 ] tmp3=(fermat_factorization(n1)[1 ])[0 ] tmp4=(fermat_factorization(n1)[1 ])[1 ] p=gcd(tmp1,tmp4) q=gcd(tmp2,tmp4) p1=next_prime(p) q1=next_prime(q) phi1=(p-1 )*(q-1 )*(p1-1 )*(q1-1 ) d1=inverse(65537 ,phi1) m1=long_to_bytes(pow (c1,d1,n1)) print (m1)print (m1+m2)
解方程有很多种解法,z3,sagemath,求根公式,当然也可以不解方程。
看得出来出题人确实没学好除法。
费马分解后,4个值为p*q
、p1*q
、p*q1
、p1*q1
,显然,4个数最大的为p1*q1
,最小的为p*q
,那和剩下的两个数求个公因数就出来了。
欧拉函数不多解释了,放两个。
1 2 3 phi = p-1 d = inverse(e,phi) m = pow (c,d,p)
1 2 3 phi = (p-1 ) * p * (q-1 ) * q * q d = inverse(e,phi) m = pow (c,d,n)
总结 建议出题人好好学习数学,不要不自量力去给全国性的比赛出题。