2023天一永安杯rsa复盘

原题

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

def gen_key(nbits, gamma):
    g = getPrime(int(nbits * gamma)) 
    alpha = 0.5 - gamma
    while True:
        a = getPrime(int(alpha * nbits))
        p = 2 * g * a + 1 
        if isPrime(p):
            break
    while True:
        b = getRandomNBitInteger(int(alpha * nbits))
        q = 2 * g * b + 1
        h = 2 * g * a * b + a + b
        if isPrime(q) and isPrime(h) and gcd(a, b) == 1:
            return p*q,a,g
        else:
            continue
        
n,a,g = gen_key(1024, 0.05)
e = 65537
c = pow(bytes_to_long(flag),e,a*g)
print(n,c,a)

'''
n=36535558847082719901201561031181835346574576610950713924924272947759193576365817762980927638691696601293089537315055413746788190208875234794229119049056299551864869870291634941246362436491006904347559559494705922259007299126640817275929491680601926404543198957206717290905220235571289759182878331893962038379
c=532997872940452282189043430008002793694788439822465302532208754231005799057972378308576109082463996551992533174546386979606697890310597738637156771564229
a=2694858406312563434474553988904403597551484373358339092528913028454100111881368126493990657117571672510331411186745639563619323775673115439
'''

解题过程

其实挺简单的,当初一看500分,觉得不是我能动的题,下来复盘了一下后悔没细看

过程如下
p*q = 2g(a+b) + 4ab*g**2 +1
a+b+2gab == h
化简得到
p*q-1 = 2gh

本题的公钥是(e,a*g)
我们可以考虑用p*q-1 = 2gh
分解得到g
n = (n-1) // 2

因为g是51位
h是约为972位
相差很大可以用yafu分解或者factordb查一下
得到

g = 1346104232461691

h = 13570850594633462506426369052182298554140635599543685835372377476383038708650421475723391142118956001358520246769650699398490037618758005241062608387057439283872260149565854577827352267289963736282502923131251179400580891491236925451166755184695335564693793568286112036468975877609637392241679

于是脚本如下

from Crypto.Util.number import *
import gmpy2

c = 532997872940452282189043430008002793694788439822465302532208754231005799057972378308576109082463996551992533174546386979606697890310597738637156771564229
a = 2694858406312563434474553988904403597551484373358339092528913028454100111881368126493990657117571672510331411186745639563619323775673115439
g = 1346104232461691
e = 65537

d = gmpy2.invert(e,(g-1)*(a-1))
print(long_to_bytes(pow(c,d,a*g)))
# b'flag{p01la4d_rHo_a1gOr1thM_r1gh4}'

后来做到了羊城杯2021的一道类似的rsa
才知道这是Common Prime RSA
常见的攻击方法有
1.修改Pollard’s rho方法分解n
2.知道a,b
3.知道g
4.分解n-1

后记

痛失线下赛,要哭哭惹

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是一个简单的Java RSA加密示例代码: ```java import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.PrivateKey; import java.security.PublicKey; import java.security.SecureRandom; import java.security.KeyFactory; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import javax.crypto.Cipher; import java.util.Base64; public class RSAEncryption { private static final String ALGORITHM = "RSA"; public static void main(String[] args) { try { // 1. 生成RSA公钥和私钥 KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(ALGORITHM); keyPairGenerator.initialize(2048, new SecureRandom()); KeyPair keyPair = keyPairGenerator.generateKeyPair(); PublicKey publicKey = keyPair.getPublic(); PrivateKey privateKey = keyPair.getPrivate(); // 2. 加密 String inputData = "Hello, World"; Cipher cipher = Cipher.getInstance(ALGORITHM); cipher.init(Cipher.ENCRYPT_MODE, publicKey); byte[] encryptedBytes = cipher.doFinal(inputData.getBytes()); String encryptedBase64 = Base64.getEncoder().encodeToString(encryptedBytes); System.out.println("Encrypted Text: " + encryptedBase64); // 3. 解密 byte[] decodedBase64 = Base64.getDecoder().decode(encryptedBase64); cipher.init(Cipher.DECRYPT_MODE, privateKey); byte[] decryptedBytes = cipher.doFinal(decodedBase64); String decryptedText = new String(decryptedBytes); System.out.println("Decrypted Text: " + decryptedText); } catch (Exception e) { e.printStackTrace(); } } } ``` 以上代码生成了一个2048位的RSA密钥对,使用公钥加密和私钥解密了一段文本。注意:使用RSA加密和解密大量数据会非常慢,一般情况下,我们会使用对称加密算法密钥加密数据,然后再使用RSA公钥加密该对称密钥,以加快加密和解密速度。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值