返回顶部

cryptohack wp (PUBLIC-KEY CRYPTOGRAPHY篇)(持续更新)

公钥密码学(持续更新)

在做这部分之前,先来了解下什么时公钥密码学吧
公钥密码学是一种密码学分支,它涉及使用加密算法和密钥对数据进行加密和解密。与对称密钥加密不同,公钥密码学使用两个密钥:一个公钥和一个私钥,因此也称为非对称密钥加密。

在公钥密码学中,公钥是公开的,可以向任何人公开,私钥则由接收方保管。加密过程中,发送方使用接收方的公钥对数据进行加密,接收方使用其私钥对数据进行解密。

公钥密码学广泛应用于安全通信、数字签名、数字证书和密钥交换等领域。最常见的公钥密码学算法包括RSA、Diffie-Hellman密钥交换、椭圆曲线密码等。

第一题(RSA Starter 1)

先来了解先RSA吧:
RSA是一种公钥密码学算法,其名称源自于发明者Ron Rivest、Adi Shamir和Leonard Adleman的姓氏。RSA算法使用两个大素数和它们的乘积作为公钥和私钥的组成部分,因此也被称为“RSA公钥加密”。

RSA算法的安全性基于一个数论问题:质因数分解。具体地说,RSA加密过程中,发送方使用接收方的公钥对消息进行加密,接收方使用其私钥对密文进行解密。在加密过程中,发送方使用一个公钥指数来加密消息,并将其发送给接收方。接收方使用其私钥来解密该消息,从而获得原始消息。

RSA算法具有许多优点,其中之一是可以安全地传输密钥,因为在使用RSA算法之前,接收方可以通过非保密通道安全地传输其公钥。此外,RSA算法还可以用于数字签名,以验证消息的来源和完整性。

尽管RSA算法在许多情况下都被广泛使用,但它仍存在某些安全性问题。例如,使用较小的密钥长度或不合适的加密模式可能导致RSA算法易受到攻击。因此,在实际应用中,需要谨慎考虑RSA算法的安全性和实现。

想更好的了解RSA,我这里推荐下两位大佬的博客:[(https://www.cnblogs.com/hykun/p/RSA.html)],https://www.tr0y.wang/2017/11/06/CTFRSA/index.html

计算(10117 mod 22663)
print((pow(101,17,22663)))

第二题(RSA Starter 2)

m =12
e = 65537
p = 17
q = 23
n = p*q
print(pow(m,e,n))

第三题(RSA Starter 3)


求欧拉函数fn

fn =(p-1)*(q-1)
print(fn)

第四题(RSA Starter 4)


求私钥d

import gmpy2
p = 857504083339712752489993810777
q = 1029224947942998075080348647219
e = 65537
fn = (p-1)*(q-1)
d = gmpy2.invert(e,fn)#求e的逆元d
print(d)

第五题(RSA Starter 5)


给了n,e,c,要想得到明文m,先得求出私钥d,要想求出d,先得求出fn,要想知道fn,得先知道p,q,由于p*q = n,且p和q互素,所以我们可以分解n
这里推荐一个分解大素数挺好用的一个网站http://factordb.com/

import gmpy2
p = 857504083339712752489993810777#分解后的p和q
q =  1029224947942998075080348647219
e = 65537
c = 77578995801157823671636298847186723593814843845525223303932
fn = (p-1)*(q-1)
n = p*q
d = gmpy2.invert(e,fn)
print(d)
m =pow(c,d,n)
print(m)

第六题(RSA Starter 6)


本题主要是了解RSA签名:
RSA签名是RSA算法的一种应用,它用于数字签名,以验证消息的来源和完整性。RSA签名可以分为两个步骤:签名和验证。

在签名过程中,签名者使用其私钥对消息进行签名。具体地说,签名者将消息哈希为一个固定长度的值,然后使用其私钥对该值进行加密,从而生成签名。接收方可以使用签名者的公钥对签名进行解密,并验证签名是否与原始消息匹配。

RSA签名的安全性基于RSA算法的离散对数问题,即找到两个大素数的乘积的质因数分解。由于该问题的计算复杂度非常高,因此RSA签名在许多情况下都被认为是安全的。

RSA签名被广泛应用于数字证书、电子商务和安全通信等领域。但需要注意的是,在实际应用中,必须谨慎地选择RSA密钥长度和哈希算法,以确保签名的安全性。
解题代码如下:

from hashlib import sha256
from Crypto.Util.number import *
N = 15216583654836731327639981224133918855895948374072384050848479908982286890731769486609085918857664046075375253168955058743185664390273058074450390236774324903305663479046566232967297765731625328029814055635316002591227570271271445226094919864475407884459980489638001092788574811554149774028950310695112688723853763743238753349782508121985338746755237819373178699343135091783992299561827389745132880022259873387524273298850340648779897909381979714026837172003953221052431217940632552930880000919436507245150726543040714721553361063311954285289857582079880295199632757829525723874753306371990452491305564061051059885803
d = 11175901210643014262548222473449533091378848269490518850474399681690547281665059317155831692300453197335735728459259392366823302405685389586883670043744683993709123180805154631088513521456979317628012721881537154107239389466063136007337120599915456659758559300673444689263854921332185562706707573660658164991098457874495054854491474065039621922972671588299315846306069845169959451250821044417886630346229021305410340100401530146135418806544340908355106582089082980533651095594192031411679866134256418292249592135441145384466261279428795408721990564658703903787956958168449841491667690491585550160457893350536334242689
m = b'crypto{Immut4ble_m3ssag1ng}'
H = bytes_to_long(sha256(m).digest())
s = pow(H,d,N)
print((s))

第七题(Factoring)


这题主要考分解大素数,正如前面所说,可以使用factordb.com网站进行分解,也可以安装库:pip install factordb-python,然后直接命令行分解:

或者使用yafu:

也可以使用python,以下是python代码:

from factordb.factordb import FactorDB
f = FactorDB(510143758735509025530880200653196460532653147)
print(f.get_factor_list())
print(f.connect())
print(f.get_factor_list())

第八题(Monoprime)

对于一个素数 p pp,它的欧拉函数值 φ ( p ) = p − 1
代码:

import gmpy2
import libnum
import binascii
from Crypto.Util.number import *
n = 171731371218065444125482536302245915415603318380280392385291836472299752747934607246477508507827284075763910264995326010251268493630501989810855418416643352631102434317900028697993224868629935657273062472544675693365930943308086634291936846505861203914449338007760990051788980485462592823446469606824421932591
e = 65537
ct = 161367550346730604451454756189028938964941280347662098798775466019463375610700074840105776873791605070092554650190486030367121011578171525759600774739890458414593857709994072516290998135846956596662071379067305011746842247628316996977338024343628757374524136260758515864509435302781735938531030576289086798942

d = gmpy2.invert(e,(n-1))
flag = pow(ct,d,n)
print(flag)
print(libnum.n2s(int(flag)))
print(bytes.fromhex(hex(flag)[2:]))
print(binascii.unhexlify(hex(flag)[2:]))
print(binascii.a2b_hex(hex(flag)[2:]))
print(long_to_bytes(flag))

第九题(Manyprime)


题目给了ct,e,n,分解n,发现如题目所说有多个素数,可以使用yafu分解,我这里直接使用factordb库(能直接生成列表,方便)。
代码如下:

n = 580642391898843192929563856870897799650883152718761762932292482252152591279871421569162037190419036435041797739880389529593674485555792234900969402019055601781662044515999210032698275981631376651117318677368742867687180140048715627160641771118040372573575479330830092989800730105573700557717146251860588802509310534792310748898504394966263819959963273509119791037525504422606634640173277598774814099540555569257179715908642917355365791447508751401889724095964924513196281345665480688029639999472649549163147599540142367575413885729653166517595719991872223011969856259344396899748662101941230745601719730556631637
e = 65537
ct = 320721490534624434149993723527322977960556510750628354856260732098109692581338409999983376131354918370047625150454728718467998870322344980985635149656977787964380651868131740312053755501594999166365821315043312308622388016666802478485476059625888033017198083472976011719998333985531756978678758897472845358167730221506573817798467100023754709109274265835201757369829744113233607359526441007577850111228850004361838028842815813724076511058179239339760639518034583306154826603816927757236549096339501503316601078891287408682099750164720032975016814187899399273719181407940397071512493967454225665490162619270814464

from factordb.factordb import FactorDB
from functools import reduce
# f = FactorDB(n)  #这里先分解然后直接生成素数
# print(f.get_factor_list())
# print(f.connect())
# print(f.get_factor_list())
p_q=[9282105380008121879, 9303850685953812323, 9389357739583927789, 10336650220878499841, 10638241655447339831, 11282698189561966721, 11328768673634243077, 11403460639036243901, 11473665579512371723, 11492065299277279799, 11530534813954192171, 11665347949879312361, 12132158321859677597, 12834461276877415051, 12955403765595949597, 12973972336777979701, 13099895578757581201, 13572286589428162097, 14100640260554622013, 14178869592193599187, 14278240802299816541, 14523070016044624039, 14963354250199553339, 15364597561881860737, 15669758663523555763, 15824122791679574573, 15998365463074268941, 16656402470578844539, 16898740504023346457, 17138336856793050757, 17174065872156629921, 17281246625998849649]

phi =reduce(lambda x,y:x*(y-1),[1]+p_q)
print(phi)
d = pow(e,-1,phi)
flag = pow(ct,d,n)
print(bytes.fromhex(hex(flag)[2:]))

第十题(Salty)

这道题给了一大堆代码,但我们看到e=1,所以m=c,直接解c,发现能解。

c = 44981230718212183604274785925793145442655465025264554046028251311164494127485
print(bytes.fromhex(hex(c)[2:]))

但可能还会有另外的情况,就是m可能会比n大,这是m = kt+c,我们可以通过爆破k来知道m:

k = 0
while 1:
    m =k*n +c
    s  = libnum.n2s(m)
    if('crypto{' in  str(s)):
        print(('flag=',s))
        
        break
    k=k+1

第十一题(Modulus Inutilis)

加密过程和上题差不多,就是把e=1改为了e=3,典型的低加密指数攻击

解题思路就是c开三次方,M^e < n 时,C = M^e ,所以对C开方就能得到M。
当M^e > n 时,此时用爆破的方法,假设我们  M^e / n 商 k 余数为c,所以M^e = kn + C,对K进行爆破,只要k满足 kn + C能够开方就可以解出M
代码如下:

from gmpy2 import iroot
import libnum
n = 17258212916191948536348548470938004244269544560039009244721959293554822498047075403658429865201816363311805874117705688359853941515579440852166618074161313773416434156467811969628473425365608002907061241714688204565170146117869742910273064909154666642642308154422770994836108669814632309362483307560217924183202838588431342622551598499747369771295105890359290073146330677383341121242366368309126850094371525078749496850520075015636716490087482193603562501577348571256210991732071282478547626856068209192987351212490642903450263288650415552403935705444809043563866466823492258216747445926536608548665086042098252335883

c= 243251053617903760309941844835411292373350655973075480264001352919865180151222189820473358411037759381328642957324889519192337152355302808400638052620580409813222660643570085177957
k = 0
while 1:
    res=iroot(c+k*n,3)
    if(res[1]==True):
        print(libnum.n2s(int(res[0])))
        break
    k=k+1

(Diffie-Hellman Starter 1)


这里主要讲Diffie-Hellman协商算法,推荐一位佬的博客:https://www.cnblogs.com/qcblog/p/9016704.html

这道题求逆,这里直接给代码:


from sympy import mod_inverse

p = 991
g = 209

d = mod_inverse(g, p)

print(d) 

Diffie-Hellman Starter 2


给出代码:
求原根
在一个模数为p的剩余系中,如果存在一个整数g,它的幂可以生成整个剩余系,那么g就被称为p的一个原根。

简单来说,如果g是p的原根,那么对于任意一个a(1<=a<=p-1),都可以找到一个整数k,使得g^k ≡ a (mod p)。

求解一个数的原根通常需要用到数论中的一些性质和算法,比较常用的有原根判别法和试除法。另外,对于一些已知的特殊模数,如素数和Carmichael数,它们的原根已经被研究得比较清楚,可以直接查表使用。

如果模数p的原根存在,那么它是唯一的,且p的原根的个数为φ(φ(p)),其中φ为欧拉函数。

from sympy.ntheory import is_primitive_root

p = 28151
g = 2

while not is_primitive_root(g, p):
    g += 1

print(g)

Diffie-Hellman Starter 3

g = 2
p = 2410312426921032588552076022197566074856950548502459942654116941958108831682612228890093858261341614673227141477904012196503648957050582631942730706805009223062734745341073406696246014589361659774041027169249453200378729434170325843778659198143763193776859869524088940195577346119843545301547043747207749969763750084308926339295559968882457872412993810129130294592999947926365264059284647209730384947211681434464714438488520940127459844288859336526896320919633919
a = 972107443837033796245864316200458246846904598488981605856765890478853088246897345487328491037710219222038930943365848626194109830309179393018216763327572120124760140018038673999837643377590434413866611132403979547150659053897355593394492586978400044375465657296027592948349589216415363722668361328689588996541370097559090335137676411595949335857341797148926151694299575970292809805314431447043469447485957669949989090202320234337890323293401862304986599884732815
求g^a mod p,没啥,直接求:

print(pow(g,a,p))

Diffie-Hellman Starter 4

Diffie-Hellman密钥交换协议是一种公钥加密算法,用于在不安全的网络中安全地交换密钥。该协议是由惠特菲尔德·迪菲(Whitfield Diffie)和马丁·赫尔曼(Martin Hellman)于1976年提出的。

Diffie-Hellman密钥交换协议的基本原理是,两个通信方(称为Alice和Bob)可以在不共享密钥的情况下,通过使用一些公共的参数(称为生成元和模数)来生成相同的密钥。这个密钥可以用于加密和解密消息,以确保消息的机密性。

具体来说,假设Alice和Bob希望安全地交换密钥,他们需要执行以下步骤:

Alice和Bob先共同选择一个大质数$p$和一个生成元$g$,并将它们公开。

Alice随机选择一个私钥$a$,计算$A = g^a \bmod p$并将$A$发送给Bob。

Bob随机选择一个私钥$b$,计算$B = g^b \bmod p$并将$B$发送给Alice。

Alice计算$K = B^a \bmod p$。

Bob计算$K = A^b \bmod p$。

现在Alice和Bob都有了相同的密钥$K$,可以用它来加密和解密消息。

Diffie-Hellman密钥交换协议的安全性基于离散对数问题的难解性。具体来说,即使知道$ga$和$gb$的值,也很难计算出$g^{ab}$的值。因此,攻击者很难通过监听Alice和Bob之间的通信来获取密钥$K$。

p=2410312426921032588552076022197566074856950548502459942654116941958108831682612228890093858261341614673227141477904012196503648957050582631942730706805009223062734745341073406696246014589361659774041027169249453200378729434170325843778659198143763193776859869524088940195577346119843545301547043747207749969763750084308926339295559968882457872412993810129130294592999947926365264059284647209730384947211681434464714438488520940127459844288859336526896320919633919
g = 2
A=70249943217595468278554541264975482909289174351516133994495821400710625291840101960595720462672604202133493023241393916394629829526272643847352371534839862030410331485087487331809285533195024369287293217083414424096866925845838641840923193480821332056735592483730921055532222505605661664236182285229504265881752580410194731633895345823963910901731715743835775619780738974844840425579683385344491015955892106904647602049559477279345982530488299847663103078045601
b= 12019233252903990344598522535774963020395770409445296724034378433497976840167805970589960962221948290951873387728102115996831454482299243226839490999713763440412177965861508773420532266484619126710566414914227560103715336696193210379850575047730388378348266180934946139100479831339835896583443691529372703954589071507717917136906770122077739814262298488662138085608736103418601750861698417340264213867753834679359191427098195887112064503104510489610448294420720
B= 518386956790041579928056815914221837599234551655144585133414727838977145777213383018096662516814302583841858901021822273505120728451788412967971809038854090670743265187138208169355155411883063541881209288967735684152473260687799664130956969450297407027926009182761627800181901721840557870828019840218548188487260441829333603432714023447029942863076979487889569452186257333512355724725941390498966546682790608125613166744820307691068563387354936732643569654017172

#A = g^a mod p
#B = g^b mod p
#K = A^b mod p or K = B^a mod p

print(pow(A,b,p))
posted @ 2023-05-09 00:18  Cryglz  阅读(420)  评论(0编辑  收藏  举报
1 2 3 1