window.onload=function(){ /*页面加载完成之后生成博客目录*/ BlogDirectory.createBlogDirectory("cnblogs_post_body","h2","h3",20); }

DASCTF 2023 & 0X401七月暑期挑战赛——ezDHKE

1、题目描述:

查看代码
from Crypto.Util.number import *
from Crypto.Cipher import AES
from hashlib import sha256
from random import randbytes, getrandbits
from flag import flag
def diffie_hellman(g, p, flag):
    alice = getrandbits(1024)
    bob = getrandbits(1024)
    alice_c = pow(g, alice, p)
    bob_c = pow(g, bob, p)
    print(alice_c , bob_c)
    key = sha256(long_to_bytes(pow(bob_c, alice, p))).digest()
    iv = b"dasctfdasctfdasc"
    aes = AES.new(key, AES.MODE_CBC, iv)
    enc = aes.encrypt(flag)
    print(enc)

def getp():
    p = int(input("P = "))
    assert isPrime(p)
    assert p.bit_length() >= 1024 and p.bit_length() <= 2048
    g = 2
    diffie_hellman(g, p, flag)

getp()

2、题目分析:

首先简化一下题目流程:
y 1 ≡ g^a ( m o d p )
y 2 ≡ g^b ( m o d p ) 
k e y ≡ g^(a ⋅ b) ( m o d p ) 
已知 y 1 , y 2 , g , p , 求 k e y , 其中 p 自己选择 ( 经典的离散对数问题 D L P ) 。
只要把 p 选正确了,再使用 d i s c r e t e l o g ( ) , a , b 就能很快出来 。
当然,这里只要求出 a 或 b 就行,没有必要两个都求。哈哈~ 
所以,关键在于 p 的选取了 ,那当然是选 p − 1 光滑数了,因子越小且越多,结果越容易得出 。

3、获取光滑数

查看代码
 # 方法一:
def myPrime(bits):
    while True:
        n = 2
        while n.bit_length() < bits:
            n *= choice(sieve_base)
        if isPrime(n + 1):
            return n + 1
print(myPrime(1024))

# 方法二:
def init():
    primes = []
    p = 1
    while len(primes) < 100:
        p = next_prime(p)
        primes.append(int(p))
    return primes


def genMyPrimeA(bits):
    while True:
        g = 2
        while g < 2 ** bits:
            g *= random.choice(primes)
        g += 1
        if isPrime(g):
            return g
            
primes = init()
print(genMyPrimeA(1024))

# 方法三:
for i in range(10000):
    p = (i<<1024)+1
    if isPrime(p):
        print(p)
        break

方法三其实为最优解,毕竟因数中的2又小又多,discrete_log()打一下结果秒出p出来了,之后便是正常的过程了

# sage
from Crypto.Util.number import *
from hashlib import *
from Crypto.Cipher import AES
p = 2492173519580396207260273583035401721936818532531412721958546193123199183809628015833810174888437077034020940145692006727703873004675257294042241804202346880422458275654783154739252083431240631535327950342922477066016603941003106019151745883988610899820235937614893707165706298487812802385444940496938785114651
A = 715335919016654816446102099094868134297789515423652054915964567424119462834464392719018232157309717997941307040048634222382457383557326993555987301288353821550940739122114753538704714160461728127423897757748356821619714662475183119381090878184436346051629155728469283154001947537385729587825693056234577943934
B = 1190605702713463149128389203183792837151025572940475499564494063011978907664624042211070458987174192231198372936172558351794117665581868503042132460328029054131214174137231671140826217310830060933673159810418076714832162830913822905905701771022323126756138610124206588856655642612360214859329692667930335795861
c = b'\xce\x01 \x8c\xc7p\xb7\x1d)\x0ci[\xd8\xb1\xcc\x86\xaf\x1b\xba.PC\x99a8o\xc2\xfc\xc8\xb5w\xecO\x10\xd6:\x8d\xf0\x16u\xe2\x89\xd9\x00\xa9\x1a\x88u'
G = Zmod(p)
a = discrete_log(G(A), G(2))
key = sha256(long_to_bytes(pow(B,a,p))).digest()
iv = b'dasctfdasctfdasc'
aes = AES.new(key,AES.MODE_CBC,iv)
flag = aes.decrypt(c)
print(flag)
# b'DASCTF{8679096d-8f55-4cf6-8403-14dcafe25e26}'

上图代码使用VScode跑的,右上角需要切换内核为Sagemath而不是Python,详细内核切换与使用请参考本博客文章

[LitCTF 2023]baby_xor

posted @ 2023-08-10 13:32  Kicky_Mu  阅读(53)  评论(0编辑  收藏  举报