RSA Assignment

首届( 2016 )全国高校密码数学挑战赛,赛题三:RSA 加密体制破译

http://blog.tolinchan.xyz/2021/11/25/%E4%BA%8C%E5%8D%81%E5%B9%B4%E4%BB%A5%E6%9D%A5%E5%AF%B9-rsa-%E5%AF%86%E7%A0%81%E7%B3%BB%E7%BB%9F%E6%94%BB%E5%87%BB%E7%BB%BC%E8%BF%B0/
https://framist.github.io/2022/01/09/%E3%80%90%E7%8E%B0%E4%BB%A3%E5%AF%86%E7%A0%81%E5%AD%A6%E3%80%91%E5%A4%A7%E4%BD%9C%E4%B8%9A/
https://blog.csdn.net/m0_63571390/article/details/122375466
https://www.tr0y.wang/2017/10/31/RSA2016/
https://www.tr0y.wang/2017/11/06/CTFRSA/
https://gitee.com/k0414_1230/rsa-DaLiBao/

共模攻击


原理

实现

Frame0 与 Frame4 同模

from gmpy2 import invert, powmod
import binascii

f = open('Frame0', 'r')
data = f.read()
n0, e0, c0 = int(data[:256], 16), int(data[256:512], 16), int(data[512:], 16)
f = open('Frame4', 'r')
data = f.read()
n4, e4, c4 = int(data[:256], 16), int(data[256:512], 16), int(data[512:], 16)


def common_module_attack(N, e1, e2, c1, c2):
    d1 = invert(e1, e2)
    d2 = (d1 * e1 - 1) // e2
    true_c2 = invert(c2, N)
    return (powmod(c1, d1, N) * powmod(true_c2, d2, N)) % N


if n0 == n4:
    ans = common_module_attack(n0, e0, e4, c0, c4)
    answer = binascii.a2b_hex(hex(ans)[2:])
    print(answer[-8:])

结果

费马分解


原理

实现

from gmpy2 import iroot, invert, powmod
import binascii

f = open('Frame10', 'r')
data = f.read()
n0, e0, c0 = int(data[:256], 16), int(data[256:512], 16), int(data[512:], 16)
p_q = iroot(n0, 2)[0]
for _ in range(200000):
    p_q += 1
    if iroot(p_q ** 2 - n0, 2)[1] == 1:
        tmp = iroot(p_q ** 2 - n0, 2)[0]
        p = (p_q + tmp)
        q = (p_q - tmp)
phi_of_frame = (p - 1) * (q - 1)
d = invert(e0, phi_of_frame)
m = powmod(c0, d, n0)
print(binascii.a2b_hex(hex(m)[-16:]))

结果

低加密指数广播攻击


原理

实现

import gmpy2
from functools import reduce
from Crypto.Util.number import long_to_bytes

e = 5
n = []
c = []
filenames = ['Frame3', 'Frame8', 'Frame12', 'Frame16', 'Frame20']
for i in filenames:
    f = open(i, 'r')
    data = f.read()
    nn = int(data[:256], 16)
    cc = int(data[512:], 16)
    n.append(nn)
    c.append(cc)


def CRT(mi, ai):
    M = reduce(lambda x, y: x * y, mi)
    ai_ti_Mi = [a * (M // m) * gmpy2.invert(M // m, m) for (m, a) in zip(mi, ai)]
    return reduce(lambda x, y: x + y, ai_ti_Mi) % M


m = CRT(n, c)
tmp = gmpy2.iroot(m, e)
tmp = hex(tmp[0])[2:]
number = int(tmp[16:24], 16)
plain = long_to_bytes(int(tmp[-16:], 16))
print(plain)

结果

因数碰撞


原理

实现

import gmpy2
import binascii

n = []
e = []
c = []
filenames = ['Frame1', 'Frame18']
for i in filenames:
    f = open(i, 'r')
    data = f.read()
    n0, e0, c0 = int(data[:256], 16), int(data[256:512], 16), int(data[512:], 16)
    n.append(n0)
    e.append(e0)
    c.append(c0)
prime = gmpy2.gcd(n[0], n[1])
if prime != 1:
    p_of_frame = prime
q_of_frame1 = n[0] // p_of_frame
q_of_frame2 = n[1] // p_of_frame

phi_of_frame1 = (p_of_frame - 1) * (q_of_frame1 - 1)
phi_of_frame2 = (p_of_frame - 1) * (q_of_frame2 - 1)

d_of_frame1 = gmpy2.invert(e[0], phi_of_frame1)
d_of_frame2 = gmpy2.invert(e[1], phi_of_frame2)

PT_of_frame1 = gmpy2.powmod(c[0], d_of_frame1, n[0])
PT_of_frame2 = gmpy2.powmod(c[1], d_of_frame2, n[1])

final_PT_of_frame1 = binascii.a2b_hex(hex(PT_of_frame1)[2:])
final_PT_of_frame2 = binascii.a2b_hex(hex(PT_of_frame2)[2:])

print(final_PT_of_frame1[-8:])
print(final_PT_of_frame2[-8:])

结果

Pollard p-1 分解


原理

实现

from gmpy2 import invert, powmod, is_prime, gcd, next_prime
import binascii

n = []
e = []
c = []
ans = []


def Pollard_p_1(N):
    a = 2
    f = a
    while 1:
        for n in range(1, 200000):
            f = powmod(f, n, N)
            if is_prime(n):
                d = gcd(f - 1, N)
                if 1 < d < N:
                    return d
                elif d >= N:
                    f = next_prime(a)
                    break
        else:
            break


filenames = ['Frame2', 'Frame6', 'Frame19']
for i in filenames:
    f = open(i, 'r')
    data = f.read()
    n0, e0, c0 = int(data[:256], 16), int(data[256:512], 16), int(data[512:], 16)
    n.append(n0)
    e.append(e0)
    c.append(c0)

for i in range(len(n)):
    p = Pollard_p_1(n[i])
    q = n[i] // p
    phi_of_frame = (p - 1) * (q - 1)
    d = invert(e[i], phi_of_frame)
    m = powmod(c[i], d, n[i])
    ans.append(binascii.a2b_hex(hex(m)[-16:]))
for i in ans:
    print(i)

结果

恢复明文


已恢复:

My secret is a f ? instein. That is "Logic will get ? m A to B. Imagin ?
(?表示未知)

可以由insten联想到爱因斯坦Albert Einstein,从而将后半部分全部恢复。

剩下数据帧只能通过猜测去尽量还原

通关密语:

My secret is a famous saying of Albert Einstein. That is "Logic will get you from A to B. Imagination will take you everywhere."
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值