从 NewStar Week2 入门 Crypto

感觉还是有点效果的,最起码一些简单的cry题目自己能够做出来了

NewStar

滴啤

题目:

不分解也能求

from Crypto.Util.number import *
import gmpy2
from flag import flag
def gen_prime(number):
    p = getPrime(number//2)
    q = getPrime(number//2)
    return p,q

m = bytes_to_long(flag.encode())
p,q = gen_prime(1024)
print(p*q)
e = 65537
d = gmpy2.invert(e,(p-1)*(q-1))
print(d%(p-1))
print(pow(m,e,p*q))
# 93172788492926438327710592564562854206438712390394636149385608321800134934361353794206624031396988124455847768883785503795521389178814791213054124361007887496351504099772757164211666778414800698976335767027868761735533195880182982358937211282541379697714874313863354097646233575265223978310932841461535936931
# 307467153394842898333761625034462907680907310539113349710634557900919735848784017007186630645110812431448648273172817619775466967145608769260573615221635
# 52777705692327501332528487168340175436832109866218597778822262268417075157567880409483079452903528883040715097136293765188858187142103081639134055997552543213589467751037524482578093572244313928030341356359989531451789166815462417484822009937089058352982739611755717666799278271494933382716633553199739292089

给了e, n, c,由于特别大,没法直接用质因数分解求得 q, p

qhint   =  q  % (p - 1)     #  其实 qhint  = dq
phint   =  d  % (p - 1)     #  其实 phint  = d
# python2
import gmpy2
import libnum
e=65537
n=16969752165509132627630266968748854330340701692125427619559836488350298234735571480353078614975580378467355952333755313935516513773552163392952656321490268452556604858966899956242107008410558657924344295651939297328007932245741660910510032969527598266270511004857674534802203387399678231880894252328431133224653544948661283777645985028207609526654816645155558915197745062569124587412378716049814040670665079480055644873470756602993387261939566958806296599782943460141582045150971031211218617091283284118573714029266331227327398724265170352646794068702789645980810005549376399535110820052472419846801809110186557162127
dp=1781625775291028870269685257521108090329543012728705467782546913951537642623621769246441122189948671374990946405164459867410646825591310622618379116284293794090970292165263334749393009999335413089903796624326168039618287078192646490488534062803960418790874890435529393047389228718835244370645215187358081805
c=0x6c78dcee37830f3ec4ab4989d40fbb595060b3fbc395d52ad26defc13372c1a3948c5388f4e450e46e016c7803133d6881e5efc3b90a4789448097c94124590b1e7949f2524d7edccd61a27691c18d090ac1f54643b563141306045417581e3b263f4ad2816136a48b106f3058b08e2a810f4ae8ef25916cc110b41ac8158ce69ecbe20fc60c1ddb20154c6646bc5142aefe47abf053a8ac949d5bc057bb18b191ad08070fe9ec5d76b1fceae685514532448c1b388b2d38e7241ac19c296e95e4e021a3a4015d909a1d53a2eb7fa86f6329f4e6c937f958be576c58fab4d9c9126999c99bb28718efc41a6f5db52b47942a2ddf21639f020b5489699cf22b46

for i in range(1,65538):
    if (dp*e-1)%i == 0:
        if n%(((dp*e-1)//i)+1)==0:
            p=((dp*e-1)//i)+1
            q=n//(((dp*e-1)//i)+1)
            phi = (p-1)*(q-1)
            d = gmpy2.invert(e,phi)%phi
            print(libnum.n2s(pow(c,d,n)))

image

不止一个pi

题目:

from flag import flag
from Crypto.Util.number import *
import gmpy2
p = getPrime(1024)
q = getPrime(1024)
n = p**3*q**2
print("q = ",q)
print("p = ",p)
m = bytes_to_long(flag.encode())
c = pow(m,65537,n)
print("c = ",c)

# q =  115478867870347527660680329271012852043845868401928361076102779938370270670897498759391844282137149013845956612257534640259997979275610235395706473965973203544920469416283181677660262509481282536465796731401967694683575843183509430017972506752901270887444490905891490955975762524187534052478173966117471143713
# p =  171790960371317244087615913047696670778115765201883835525456016207966048658582417842936925149582378305610304505530997833147251832289276125084339614808085356814202236463900384335878760177630501950384919794386619363394169016560485152083893183420911295712446925318391793822371390439655160077212739260871923935217
# c =  4459183928324369762397671605317600157512712503694330767938490496225669985050002776253470841193156951087663107866714426230222002399666306287642591077990897883174134404896800482234781531592939043551832049756571987010173667074168282355520711905659013076509353523088583347373358980842707686611157050425584598825151399870268083867269912139634929397957514376826145870752116583185351576051776627208882377413433140577461314504762388617595282085102271510792305560608934353515552201553674287954987323321512852114353266359364282603487098916608302944694600227628787791876600901537888110093703612414836676571562487005330299996908873589228072982641114844761980143047920770114535924959765518365614709272297666231481655857243004072049094078525569460293381479558148506346966064906164209362147313371962567040047084516510135054571080612077333228195608109065475260832580192321853906138811139036658485688320161530131239854003996457871663456850196483520239675981391047452381998620386899101820782421605287708727667663038905378115235163773867508258208867367314108701855709002634592329976912239956212490788262396106230191754680813790425433763427315230330459349320412354189010684525105318610102936715203529222491642807382215023468936755584632849348996666528981269240867612068382243822300418856599418223875522408986596925018975565057696218423036459144392625166761522424721268971676010427096379610266649911939139451989246194525553533699831110568146220347603627745407449761792135898110139743498767543521297525802809254842518002190381508964357001211353997061417710783337

不能直接将p**3​当作新p​,q**2​当作新q

# from flag import flag
from Crypto.Util.number import *
import gmpy2
# p = getPrime(1024)
# q = getPrime(1024)
# n = p**3*q**2
# c = pow(m,65537,n)
# print("q = ",q)
# print("p = ",p)
# m = bytes_to_long(flag.encode())
# c = pow(m,65537,n)
# print("c = ",c)

q =  115478867870347527660680329271012852043845868401928361076102779938370270670897498759391844282137149013845956612257534640259997979275610235395706473965973203544920469416283181677660262509481282536465796731401967694683575843183509430017972506752901270887444490905891490955975762524187534052478173966117471143713
p =  171790960371317244087615913047696670778115765201883835525456016207966048658582417842936925149582378305610304505530997833147251832289276125084339614808085356814202236463900384335878760177630501950384919794386619363394169016560485152083893183420911295712446925318391793822371390439655160077212739260871923935217
c =  4459183928324369762397671605317600157512712503694330767938490496225669985050002776253470841193156951087663107866714426230222002399666306287642591077990897883174134404896800482234781531592939043551832049756571987010173667074168282355520711905659013076509353523088583347373358980842707686611157050425584598825151399870268083867269912139634929397957514376826145870752116583185351576051776627208882377413433140577461314504762388617595282085102271510792305560608934353515552201553674287954987323321512852114353266359364282603487098916608302944694600227628787791876600901537888110093703612414836676571562487005330299996908873589228072982641114844761980143047920770114535924959765518365614709272297666231481655857243004072049094078525569460293381479558148506346966064906164209362147313371962567040047084516510135054571080612077333228195608109065475260832580192321853906138811139036658485688320161530131239854003996457871663456850196483520239675981391047452381998620386899101820782421605287708727667663038905378115235163773867508258208867367314108701855709002634592329976912239956212490788262396106230191754680813790425433763427315230330459349320412354189010684525105318610102936715203529222491642807382215023468936755584632849348996666528981269240867612068382243822300418856599418223875522408986596925018975565057696218423036459144392625166761522424721268971676010427096379610266649911939139451989246194525553533699831110568146220347603627745407449761792135898110139743498767543521297525802809254842518002190381508964357001211353997061417710783337
# n = p**3*q**2
# print(n)
n = 67609224996391014657776133236526961533287515075910005725386020739264421275993019731805499802328571980649928650621461743405933956465243606933968729054670292368212915305560845370775950912115842928349107397670366517222166661617404986609504508291645704089145910015426549092047602412464939974501602148388847128249825208504872590147534157725603286814584759946564578191861934604965746249723126980222803510460487101017242712811360609163376622387652827736571291760564915989586263687577815391845465766405508854253814480782572865550668118935076780358023998993793200124280017936904299998453398067814115123088442955540152596535353785062038981697307799069159656803188314359784560656028074439207263178942722631441593527222608594274571727909586852252656885853154917351354959802861484086853081975649160903589296750127546698401571547974182793816198542270904704439942944115164260287190076970580790466617950743753891962621919709132128185674637022152689646556391654735323050076777366347728609629474408132965367020232235933080733001377855172880131884496557567037082325816010736648622012227740532094614654576116067689232387975630819161018205673935853719811922753881794582830722709269617683661709608702161928400974871937453218763448793806431101263383123991454069867570680539777306445852495973613945204532199412618904051681905370709729775846504418305922135621455910928679594920450217355003557571517666044348687697909412179289383980074158313690311776265677874914291769162846202102200533579262207472340679940536119321613067181556618761704057125174709398765878366900497
e = 65537
# phi = n-1
phi_p3 = p**2 * (p-1)
phi_q2 = q * (q-1)
phi = phi_p3 * phi_q2
d = gmpy2.invert(e,phi)
print(d)
m = pow(c,d,n)
print(m)
print(long_to_bytes(m))

halfcandecode

题目:

from Crypto.Util.number import *
import gmpy2
from flag import flag
import os
from hashlib import md5

def gen_prime(number):
    p = getPrime(number // 2)
    q = gmpy2.next_prime(p)
    return p * q

def md5_hash(m):
    return md5(m.encode()).hexdigest()
e = 65537
n = gen_prime(1024)
m1 = bytes_to_long(flag[:len(flag) // 2].encode() + os.urandom(8))
c1 = pow(m1, e, n)
m2 = flag[len(flag) // 2:]
with open("out.txt","w") as f:
    f.write(str(n) + '\n')
    f.write(str(c1) + '\n')
    for t in m2:
        f.write(str(md5_hash(t))+'\n')

# 113021375625152132650190712599981988437204747209058903684387817901743950240396649608148052382567758817980625681440722581705541952712770770893410244646286485083142929097056891857721084849003860977390188797648441292666187101736281034814846427200984062294497391471725496839508139522313741138689378936638290593969
# 43054766235531111372528859352567995977948625157340673795619075138183683929001986100833866227688081563803862977936680822407924897357491201356413493645515962458854570731176193055259779564051991277092941379392700065150286936607784073707448630150405898083000157174927733260198355690620639487049523345380364948649
# 4a8a08f09d37b73795649038408b5f33
# 03c7c0ace395d80182db07ae2c30f034
# e1671797c52e15f763380b45e841ec32
# b14a7b8059d9c055954c92674ce60032
# e358efa489f58062f10dd7316b65649e
# cfcd208495d565ef66e7dff9f98764da
# b14a7b8059d9c055954c92674ce60032
# 8fa14cdd754f91cc6554c9e71929cce7
# 0cc175b9c0f1b6a831c399e269772661
# 4a8a08f09d37b73795649038408b5f33
# e358efa489f58062f10dd7316b65649e
# cfcd208495d565ef66e7dff9f98764da
# 4b43b0aee35624cd95b910189b3dc231
# cbb184dd8e05c9709e5dcaedaa0495cf

flag分为两部分,第一部分用了RSA加密,这部分的p​和q​其实很近,但是yafu可以分解,第二部分是用md5加密,可以爆破:

from Crypto.Util.number import long_to_bytes
import gmpy2
import hashlib

# strings = "1234567890QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm/'_}{-"
# for t in strings:
#     hash1 = hashlib.md5(t.encode()).hexdigest()
#     if hash1 == "cbb184dd8e05c9709e5dcaedaa0495cf":
#         print(t)

#cse_t0_fact0r} 手撕出来的

p = 10631151190024160908870967192522097752991652918777416177941351782447314225123009693276679810786266997133099934443701772661928189884235742113123409596993841
q = 10631151190024160908870967192522097752991652918777416177941351782447314225123009693276679810786266997133099934443701772661928189884235742113123409596993409
e = 65537
n = p * q
c = 43054766235531111372528859352567995977948625157340673795619075138183683929001986100833866227688081563803862977936680822407924897357491201356413493645515962458854570731176193055259779564051991277092941379392700065150286936607784073707448630150405898083000157174927733260198355690620639487049523345380364948649
phi = (p-1) * (q-1)
d = gmpy2.invert(e,phi)
m = pow(c,d,n)
print(long_to_bytes(m))
# b'flag{two_cloab\xdbxD-K\x01J\xe5'
# flag{two_cloabcse_t0_fact0r}

Rotate Xor

题目:

from secret import flag
from os import urandom
from pwn import xor
from Cryptodome.Util.number import *
k1 = getPrime(64)
k2 = getPrime(64)
ROUND = 12
ciphertext = xor(flag, long_to_bytes(k1))
def round_rotate_left(num, step):
    return ((num) << step | num >> (64-step)) & 0xffffffffffffffff
def encrypt_key(key):

    for _ in range(ROUND):
        key = round_rotate_left(key, 3) ^ k2

    return key
print('ciphertext =', ciphertext)
print('enc_k1 =', encrypt_key(k1))
print('k2 =', k2)

# ciphertext = b'\x8dSyy\xd2\xce\xe2\xd2\x98\x0fth\x9a\xc6\x8e\xbc\xde`zl\xc0\x85\xe0\xe4\xdfQlc'
# enc_k1 = 7318833940520128665
# k2 = 9982833494309156947

有四个位运算,

image

其余的按照逻辑逆向回去就好了:

from Crypto.Util.number import long_to_bytes
from pwn import xor
step = 3
enc_k1 = 7318833940520128665
k2 = 9982833494309156947
for i in range(12):
    enc_k1 = enc_k1 ^ k2
    enc_k1 = (enc_k1 >> step | enc_k1 << 64-step & 0xffffffffffffffff) & 0xffffffffffffffff
    # print(enc_k1)

ciphertext = b'\x8dSyy\xd2\xce\xe2\xd2\x98\x0fth\x9a\xc6\x8e\xbc\xde`zl\xc0\x85\xe0\xe4\xdfQlc'
k1 = long_to_bytes(enc_k1)
flag = xor(ciphertext,k1)
print(flag)

partial decrypt

题目:

from secret import flag
from Crypto.Util.number import *

m = bytes_to_long(flag)
e = 65537
p = getPrime(512)
q = getPrime(512)

n = p*q 

c = pow(m,e,n)

dp = inverse(e, (p-1))
dq = inverse(e, (q-1))
m1 = pow(c,dp, p)
m2 = pow(c,dq, q)
q_inv = inverse(q, p)
h = (q_inv*(m1-m2)) % p
print('m2 =', m2)
print('h =', h)
print('q =', q)

# m2 = 4816725107096625408335954912986735584642230604517017890897348901815741632668751378729851753037917164989698483856004115922538576470127778342121497852554884
# h = 4180720137090447835816240697100630525624574275
# q = 7325294399829061614283539157853382831627804571792179477843187097003503398904074108324900986946175657737035770512213530293277111992799331251231223710406931

首先,我们需要在在生成私钥公钥时,多生成几个数:
我们的d是e对Φ(n)的逆元,我们现在需要另外2个逆元(分别是对(p-1)和(q-1)的),即:

  1. 计算dP,使得dPe = 1 mod(p-1),即 dP = (1/e) mod (p-1)
  2. 2:计算dQ,使得dQe = 1 mod(q-1),即dQ = (1/e) mod (q-1)
    此外需要第三个元素,既q对p的逆元
  3. 计算qInv,使得qInv * q = 1 mod p,即qInv = (1/q) mod p
    私钥是 (p, q, dP, dQ, qInv)

计算:
使用公钥加密:
若要加密明文m,则需要计算c = m^e mod n,c为密文。

使用私钥解密:
m1=c^dP mod p
m2=c^dQ mod q
h= q_inv(m1-m2) mod p
m = m2 + hq
m就是明文。

from Crypto.Util.number import *

m2 = 4816725107096625408335954912986735584642230604517017890897348901815741632668751378729851753037917164989698483856004115922538576470127778342121497852554884
h = 4180720137090447835816240697100630525624574275
q = 7325294399829061614283539157853382831627804571792179477843187097003503398904074108324900986946175657737035770512213530293277111992799331251231223710406931
m = m2 + h*q

strings = long_to_bytes(m)
print(strings)

发布者

AndyNoel

一杯未尽,离怀多少。