[CryptoHack] Public-key Cryptography Partial Solutions

Factoring

So far we’ve been using the product of small primes for the modulus, but small primes aren’t much good for RSA as they can be factorised using modern methods.

What is a “small prime”? There was an RSA Factoring Challenge with cash prizes given to teams who could factorise RSA moduli. This gave insight to the public into how long various key sizes would remain safe. Computers get faster, algorithms get better, so in cryptography it’s always prudent to err on the side of caution.

These days, using primes that are at least 1024 bits long is recommended—multiplying two such 1024 primes gives you a modulus that is 2048 bits large. RSA with a 2048-bit modulus is called RSA-2048.

Some say that to really remain future-proof you should use RSA-4096 or even RSA-8192. However, there is a tradeoff here; it takes longer to generate large prime numbers, plus modular exponentiations are predictably slower with a large modulus.

Factorise the 150-bit number 510143758735509025530880200653196460532653147into its two constituent primes. Give the smaller one as your answer.

Resources:

方式1:质因数分解网站:http://factordb.com/
在这里插入图片描述

方式2:Using sagemath

# in SageMath
factor(510143758735509025530880200653196460532653147 )
# 19704762736204164635843 * 25889363174021185185929

相关视频:https://www.youtube.com/watch?v=SmJRKo4XL18&ab_channel=JohnHammond

这个视频内容是有关RSA整数分解的一道题,作用使用python的pwntools模块来维持一个http session 通过该session完成提交整数分解的结果。质因数分解用的是python primefac module。

summary:
现有的整数分解算法可以快速分解“小整数”。因此RSA中小模数N是不安全的。

Monoprime

Why is everyone so obsessed with multiplying two primes for RSA. Why not just use one?

Challenge files:

Resources:

#!/usr/bin/env python3
from Crypto.Util import number
n = 171731371218065444125482536302245915415603318380280392385291836472299752747934607246477508507827284075763910264995326010251268493630501989810855418416643352631102434317900028697993224868629935657273062472544675693365930943308086634291936846505861203914449338007760990051788980485462592823446469606824421932591                                                                  
e = 65537
ct = 161367550346730604451454756189028938964941280347662098798775466019463375610700074840105776873791605070092554650190486030367121011578171525759600774739890458414593857709994072516290998135846956596662071379067305011746842247628316996977338024343628757374524136260758515864509435302781735938531030576289086798942

if number.isPrime(n):
    phi_n = n - 1
    d = number.inverse(e, phi_n)
    pt = pow(ct, d, n)
    pt = number.long_to_bytes(pt).decode()
    print(pt)

Manyprime

题目描述
Using one prime factor was definitely a bad idea so I’ll try using over 30 instead.

If it’s taking forever to factorise, read up on factorisation algorithms and make sure you’re using one that’s optimised for this scenario.

Challenge files:

Resources:

首先对N进行素因子分解

# in sagemath
n = 580642391898843192929563856870897799650883152718761762932292482252152591279871421569162037190419036435041797739880389529593674485555792234900969402019055601781662044515999210032698275981631376651117318677368742867687180140048715627160641771118040372573575479330830092989800730105573700557717146251860588802509310534792310748898504394966263819959963273509119791037525504422606634640173277598774814099540555569257179715908642917355365791447508751401889724095964924513196281345665480688029639999472649549163147599540142367575413885729653166517595719991872223011969856259344396899748662101941230745601719730556631637
e = 65537
ct = 320721490534624434149993723527322977960556510750628354856260732098109692581338409999983376131354918370047625150454728718467998870322344980985635149656977787964380651868131740312053755501594999166365821315043312308622388016666802478485476059625888033017198083472976011719998333985531756978678758897472845358167730221506573817798467100023754709109274265835201757369829744113233607359526441007577850111228850004361838028842815813724076511058179239339760639518034583306154826603816927757236549096339501503316601078891287408682099750164720032975016814187899399273719181407940397071512493967454225665490162619270814464
ecm.factor(n)

得到素分解之后,

  1. 计算N的Euler totient
  2. 求e的逆元,得到d
  3. 执行RSA解密算法
  4. 将数字转换为字符串,得到flag
#!/usr/bin/env python3
from Crypto.Util import number
n = 580642391898843192929563856870897799650883152718761762932292482252152591279871421569162037190419036435041797739880389529593674485555792234900969402019055601781662044515999210032698275981631376651117318677368742867687180140048715627160641771118040372573575479330830092989800730105573700557717146251860588802509310534792310748898504394966263819959963273509119791037525504422606634640173277598774814099540555569257179715908642917355365791447508751401889724095964924513196281345665480688029639999472649549163147599540142367575413885729653166517595719991872223011969856259344396899748662101941230745601719730556631637
e = 65537
ct = 320721490534624434149993723527322977960556510750628354856260732098109692581338409999983376131354918370047625150454728718467998870322344980985635149656977787964380651868131740312053755501594999166365821315043312308622388016666802478485476059625888033017198083472976011719998333985531756978678758897472845358167730221506573817798467100023754709109274265835201757369829744113233607359526441007577850111228850004361838028842815813724076511058179239339760639518034583306154826603816927757236549096339501503316601078891287408682099750164720032975016814187899399273719181407940397071512493967454225665490162619270814464

# 通过sage对N进行分解得到
factors = [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_n = 1
for i in factors:
    phi_n *= i-1
d = number.inverse(e, phi_n)  # get private key
pt = number.long_to_bytes(pow(ct, d, n)).decode()
print(pt)

在线的sagemath: https://sagecell.sagemath.org/
sage lesson: https://github.com/fredstro/sage-lesson-nt
sage 官方教程https://doc.sagemath.org/html/en/index.html
博客教程1:https://cocalc.com/share/public_paths/embed/ee63291fa9aadeb8d5830f5c518cddb466501a70
博客教程2: https://blog.devgenius.io/sagemath-doing-math-in-python-8c34765254f7

Salty

题目描述:
Smallest exponent should be fastest, right?
Challenge files:

由于公钥 e = 1 e=1 e=1,因此无论 ϕ ( n ) \phi(n) ϕ(n)的值为多少,私钥 d d d始终为1。

#!/usr/bin/env python3
from Crypto.Util import number
n = 110581795715958566206600392161360212579669637391437097703685154237017351570464767725324182051199901920318211290404777259728923614917211291562555864753005179326101890427669819834642007924406862482343614488768256951616086287044725034412802176312273081322195866046098595306261781788276570920467840172004530873767                                                                  
e = 1
ct = 44981230718212183604274785925793145442655465025264554046028251311164494127485
d = 1

pt = pow(ct, d, n)
flag = number.long_to_bytes(pt).decode()
print(flag)

这道题告诉我们,RSA的公钥采用 e = 1 e=1 e=1不安全。

Modulus Inutilis

My primes should be more than large enough now!

Challenge files:

#!/usr/bin/env python3
import gmpy2
from Crypto.Util import number

"""
Because m is small, m^3 is close to n, so we can compute the 3-th root of  c + k*n where k=0,1,2...
"""

n = 17258212916191948536348548470938004244269544560039009244721959293554822498047075403658429865201816363311805874117705688359853941515579440852166618074161313773416434156467811969628473425365608002907061241714688204565170146117869742910273064909154666642642308154422770994836108669814632309362483307560217924183202838588431342622551598499747369771295105890359290073146330677383341121242366368309126850094371525078749496850520075015636716490087482193603562501577348571256210991732071282478547626856068209192987351212490642903450263288650415552403935705444809043563866466823492258216747445926536608548665086042098252335883
e = 3
ct = 243251053617903760309941844835411292373350655973075480264001352919865180151222189820473358411037759381328642957324889519192337152355302808400638052620580409813222660643570085177957

def low_e_attack(ct,e,n):
    i = 0
    while True:
        
        y, r = gmpy2.iroot(ct + i * n, e) # Return the integer n-th root of x and boolean value that is True iff the root is exact. x >= 0. n > 0.
  
        if r == True:
            print(f"i = {i}")
            flag = number.long_to_bytes(y).decode()
            print(flag)
            exit()
        i = i + 1

if __name__ == "__main__":
    low_e_attack(ct,e,n)

Diffie-Hellman Starter 1

The set of integers modulo n, together with the operations of both addition and multiplication is a ring. This means that adding or multiplying any two elements in the set returns another element in the set.

When the modulus is prime: n = p, we are guaranteed an inverse of every element in the set, and so the ring is promoted to a field. We refer to this field as a finite field F p F_p Fp.

The Diffie-Hellman protocol works with elements of some finite field Fp, where the prime modulus is typically a large prime.

Given the prime p = 991, and the element g = 209, find the inverse element d such that g * d mod 991 = 1.

#!/usr/bin/env python3

from Crypto.Util import number

p = 991
g = 209
d = number.inverse(g, p)
print(f"d = {d}")
RSA非对称加密中,使用对等方的公钥通常涉及数据加密、密钥交换或数字签名验证等场景。以下是具体的应用方式和实现细节: ### 数据加密 在数据加密过程中,发送方使用接收方提供的公钥对明文数据进行加密,生成的密文只能通过对应的私钥解密。这种方式确保了只有持有私钥的接收方才能读取信息,保障了通信的安全性。 例如,在iOS开发中,若需要使用PEM格式的公钥进行加密,首先需要将公钥从PEM格式解析为可用的密钥对象,然后使用该公钥对数据进行加密。以下是一个简单的Python示例,展示了如何使用`cryptography`库完成这一过程: ```python from cryptography.hazmat.primitives import serialization from cryptography.hazmat.primitives.asymmetric import padding from cryptography.hazmat.primitives import hashes # 加载PEM格式的公钥 with open("public_key.pem", "rb") as f: public_key = serialization.load_pem_public_key( f.read() ) # 使用公钥加密数据 plaintext = b"Secret message" ciphertext = public_key.encrypt( plaintext, padding.OAEP( mgf=padding.MGF1(algorithm=hashes.SHA256()), algorithm=hashes.SHA256(), label=None ) ) print("Encrypted data:", ciphertext) ``` ### 密钥交换 RSA还可以用于安全地交换对称加密算法所需的密钥。在这种情况下,发送方生成一个随机的对称密钥,并使用接收方的公钥对其进行加密。接收方收到加密后的密钥后,使用自己的私钥解密并获取对称密钥。随后,双方可以使用该对称密钥进行高效的数据加密和解密[^3]。 ### 数字签名验证 数字签名是另一种常见的应用场景,它利用RSA的非对称特性来验证数据的完整性和真实性。发送方使用自己的私钥对数据进行签名,而接收方则使用发送方的公钥验证签名的有效性。如果签名验证成功,则表明数据未被篡改且确实来自签名者。 以下是一个使用Python的`cryptography`库进行数字签名验证的示例: ```python from cryptography.hazmat.primitives import hashes from cryptography.hazmat.primitives.asymmetric import padding from cryptography.hazmat.primitives.serialization import load_pem_public_key # 加载PEM格式的公钥 with open("public_key.pem", "rb") as f: public_key = load_pem_public_key(f.read()) # 验证签名 message = b"Message to be signed" signature = b"Signature generated by the private key" try: public_key.verify( signature, message, padding.PSS( mgf=padding.MGF1(hashes.SHA256()), salt_length=padding.PSS.MAX_LENGTH ), hashes.SHA256() ) print("Signature is valid.") except Exception as e: print("Signature is invalid:", e) ``` ### 公钥的格式与管理 在实际应用中,公钥可能以多种格式存在,包括PEM(Privacy Enhanced Mail)、DER(Distinguished Encoding Rules)以及直接提供模数(n)和公开幂(e)的情况。PEM格式的公钥通常以`-----BEGIN PUBLIC KEY-----`开头,并以Base64编码形式存储;而DER格式则是二进制形式的公钥数据。此外,某些场景下可能会直接给出模数n和公开幂e的十六进制值,这时需要手动构造公钥对象[^1]。 对于物联网设备的身份验证,每台设备会生成并绑定一个随机的公钥,同时还会发送设备证书以供CA中心验证。这种方法结合了公钥加密和证书机制,进一步增强了系统的安全性[^5]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值