crypto-rsarsa(江苏工匠杯 CTF)

又是一题pwn结合crypto,记录一下。听说是鹤城杯2021 babyrsa类似题目。
源码challenge.sage:

for _ in range(3):
    p = random_prime(2^1024)
    q = random_prime(2^1024)
    n = p*q
    p1=p>>724
    ct=n * inverse_mod(q % (2 ** 265), 2^265) % 2^265
    print('p1=',p1)
    print('ct=',ct)
    print("n=",n)
    e = 65537
    alarm(80)
    m = randint(2,n-1)
    c=pow(m,e,n)
    print('c=', c)
    print('---------------------------------------------')
    m1 = int(input("m="))
    print('---------------------------------------------')
    print()
    if m1!=m:
        print("Nope")
        exit()

print(open("flag.txt","r").read())

分析一下逻辑,一共三轮RSA加密,p,q 是1024bit随机素数, e=65537,给出 p1p 的高300bit值,给出 n=p*q ,给出 c t = n × q − 1 m o d    2 265 ct=n \times q^{-1} \mod 2^{265} ct=n×q1mod2265
另外还给出明文 m 经过RSA加密后的密文 c
需要解出明文后进入下一轮。

推导一下;
实际上 c t = n × q − 1 m o d    2 265 = p m o d    2 265 ct=n \times q^{-1} \mod 2^{265}=p \mod 2^{265} ct=n×q1mod2265=pmod2265也就是p的低265bit;已知p的高位和低位套coppersmith攻击脚本求解。

最终exp:

#sage
from pwn import *

context.log_level = "DEBUG"
conn = remote("223.112.5.156", 54864)

def solveit(p1,ct,n,c):
    mod=pow(2,265)
    pbar=(p1<<724)+ct
    PR.<x> = PolynomialRing(Zmod(n))
    for i in range(32):
        f=pbar+x*mod*32
        f=f.monic()
        pp=f.small_roots(X=2^454,beta=0.4)
        if(pp):
            break
        pbar+=mod
    assert pp
    p=pbar+pp[0]*32*mod
    q=n//Integer(p)
    e=65537
    phi=(p-1)*(q-1)
    d = inverse_mod(e, phi)
    m = pow(c, d, n)
    return m

for _ in range(3):
    conn.recvuntil(b'p1=')
    params = conn.recvuntil(b'm=')
    params=params.split(b'\n')
    p1=int(params[0][1:])
    ct=int(params[1][4:])
    n=int(params[2][3:])
    c=int(params[3][3:])
    #print(p1,ct,n,c)
    m=solveit(p1,ct,n,c)
    print(m)
    conn.sendline(str(m))

conn.recvall()

### 使用 Crypto-JS 实现 RSA 加解密 需要注意的是,`CryptoJS` 主要专注于对称加密算法如AES,并不直接提供RSA加解密功能[^3]。对于RSA加解密,在JavaScript环境中通常会使用专门的库比如 `jsencrypt` 来处理。 然而,为了满足需求,下面展示了一个结合 `JSEncrypt` 和 `CryptoJS` 的混合方案来实现公私钥对消息的签名验证过程中的部分环节——即先用AES加密数据再用RSA保护AES秘钥的方式: #### 安装依赖包 首先确保已经引入了必要的库文件: - JSEncrypt 用于生成RSA密钥对以及执行基于这些密钥的操作。 - CryptoJS 提供各种实用工具函数和分组密码模式的支持。 可以通过CDN链接快速加载这两个库到HTML页面中: ```html <script src="https://cdnjs.cloudflare.com/ajax/libs/jsencrypt/3.0.0-rc.1/jsencrypt.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.0.0/crypto-js.min.js"></script> ``` #### 数据加密流程 ##### AES加密待传输的数据并保存随机产生的AES Key ```javascript function generateAesKey() { const charset = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; let key = ''; while (key.length < 32) { // AES-256 requires a 256-bit (32-byte) key. key += charset.charAt(Math.floor(Math.random() * charset.length)); } return key; } // Generate an IV for encryption const iv = CryptoJS.lib.WordArray.random(16); // Encrypt the message using AES with CBC Mode and PKCS7 Padding function encryptMessage(message, aesKey) { const cipherText = CryptoJS.AES.encrypt( message, CryptoJS.enc.Utf8.parse(aesKey), { iv: iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 } ); return cipherText.ciphertext.toString(CryptoJS.enc.Base64); } ``` ##### 使用接收方提供的公钥加密之前得到的AES Key ```javascript function rsaEncrypt(publicKeyStr, dataToBeEncrypted){ var encryptor = new JSEncrypt(); encryptor.setPublicKey(publicKeyStr); return encryptor.encrypt(dataTo be Encrypted); } ``` #### 解密端操作 在另一侧接收到上述两部分内容之后,则按照相反顺序完成整个还原工作: 1. 利用本地存储着对应的私钥解开被保护起来的那个临时使用的AES session key; 2. 接下来就可利用这个恢复出来的session key去解锁实际的消息体了; 这里省略了解码的具体逻辑因为这取决于具体应用场景下的协议设计。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值