[山海关crypto 训练营 day7]

该文章涉及一种使用椭圆曲线加密(ECC)的旗标加密挑战。首先,它生成公钥和私钥,然后计算共享密钥,通过SHA1哈希得到AES加密密钥。接着,使用AES-CBC模式加密FLAG并发送。解密过程涉及到解决椭圆曲线离散对数问题(ECDLP)。文章提供了相关数学运算和代码实现,包括Pohlig-Hellman攻击的防护措施。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

日常鼓励自己:欲望以提升热忱,毅力以磨平高山。

Exceptional Curves(100pt)

题目描述

在这里插入图片描述

题目代码与相关数据

from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
from random import randint
import hashlib

FLAG = b'crypto{??????????????????????}'


def gen_public_key():
    private = randint(1, E.order() - 1)
    public = G * private
    return(public, private)


def shared_secret(public_key, private_key):
    S = public_key * private_key
    return S.xy()[0]


def encrypt_flag(flag):
    # Bob's public key
    b_x = 0x7f0489e4efe6905f039476db54f9b6eac654c780342169155344abc5ac90167adc6b8dabacec643cbe420abffe9760cbc3e8a2b508d24779461c19b20e242a38
    b_y = 0xdd04134e747354e5b9618d8cb3f60e03a74a709d4956641b234daa8a65d43df34e18d00a59c070801178d198e8905ef670118c15b0906d3a00a662d3a2736bf
    B = E(b_x, b_y)
    # Calculate shared secret
    A, nA = gen_public_key()
    print(f'Public Key: {A}')
    secret = shared_secret(B, nA)
    # Derive AES key from shared secret
    sha1 = hashlib.sha1()
    sha1.update(str(secret).encode('ascii'))
    key = sha1.digest()[:16]
    # Encrypt flag
    iv = os.urandom(16)
    cipher = AES.new(key, AES.MODE_CBC, iv)
    ciphertext = cipher.encrypt(pad(FLAG, 16))
    # Prepare encryption to send
    data = {}
    data['iv'] = iv.hex()
    data['encrypted_flag'] = ciphertext.hex()
    return data


# Curve params
p = 0xa15c4fb663a578d8b2496d3151a946119ee42695e18e13e90600192b1d0abdbb6f787f90c8d102ff88e284dd4526f5f6b6c980bf88f1d0490714b67e8a2a2b77
a = 0x5e009506fcc7eff573bc960d88638fe25e76a9b6c7caeea072a27dcd1fa46abb15b7b6210cf90caba982893ee2779669bac06e267013486b22ff3e24abae2d42
b = 0x2ce7d1ca4493b0977f088f6d30d9241f8048fdea112cc385b793bce953998caae680864a7d3aa437ea3ffd1441ca3fb352b0b710bb3f053e980e503be9a7fece

# Define curve
E = EllipticCurve(GF(p), [a, b])

# Protect against Pohlig-Hellman Algorithm
assert is_prime(E.order())

# Create generator
G = E.gens()[0]
print(f'Generator: {G}')

encrypted_flag = encrypt_flag(FLAG)
print(encrypted_flag)

#Generator: (3034712809375537908102988750113382444008758539448972750581525810900634243392172703684905257490982543775233630011707375189041302436945106395617312498769005 : 4986645098582616415690074082237817624424333339074969364527548107042876175480894132576399611027847402879885574130125050842710052291870268101817275410204850 : 1)
#Public Key: (4748198372895404866752111766626421927481971519483471383813044005699388317650395315193922226704604937454742608233124831870493636003725200307683939875286865 : 2421873309002279841021791369884483308051497215798017509805302041102468310636822060707350789776065212606890489706597369526562336256272258544226688832663757 : 1)
#{'iv': '719700b2470525781cc844db1febd994', 'encrypted_flag': '335470f413c225b705db2e930b9d460d3947b3836059fb890b044e46cbb343f0'}

题目分析

跟昨天的上个题基本类似,也是获得这个secret作为密钥,通过AES解密flag。
根据题目名字提示,本题考查的是smart attack

具体操作

脚本小子~~~~后期补上详细分析

p = 0xa15c4fb663a578d8b2496d3151a946119ee42695e18e13e90600192b1d0abdbb6f787f90c8d102ff88e284dd4526f5f6b6c980bf88f1d0490714b67e8a2a2b77
a = 0x5e009506fcc7eff573bc960d88638fe25e76a9b6c7caeea072a27dcd1fa46abb15b7b6210cf90caba982893ee2779669bac06e267013486b22ff3e24abae2d42
b = 0x2ce7d1ca4493b0977f088f6d30d9241f8048fdea112cc385b793bce953998caae680864a7d3aa437ea3ffd1441ca3fb352b0b710bb3f053e980e503be9a7fece

E = EllipticCurve(GF(p), [a, b])
q = E.cardinality()
assert(p == q)

# base point
G = E(0x39f15e024d44228fd11c58a71c312fd64167c7d249d5677da0dfb4b9c3ed0f90701837a5e77b5a2b74433d7fbe027cd0c73b5aa7b300f7384521af0dc283dc6d,
      0x5f3636a89167a6fbb7b7d1ad97d11c70756835b5f1273e20c06d9e022d74648ec22a3f92c378196d137c3f2027a67381be79e1c0d65cd9b61211a77a3842c8b2)

# Alice's public key point
A = E(0x5aa8b5cf3124c552881ba67c14c863bb2ff30d960fe41b61123d2025cdddf0ea75e92d76326be9fb09b9a32373fc278ac8d5cf5ca83b9e517ce347c6879bef51,
      0x2e3ddec1b35930b1039351b2814252186b30ce27ce15eda4351428868ae8593ab8c61c034ba10041cce205d7f7102c292f30ac5f3d2a2c2f3a463d837df070cd)

# Bob's public key point
B = E(0x7f0489e4efe6905f039476db54f9b6eac654c780342169155344abc5ac90167adc6b8dabacec643cbe420abffe9760cbc3e8a2b508d24779461c19b20e242a38, 
  0xdd04134e747354e5b9618d8cb3f60e03a74a709d4956641b234daa8a65d43df34e18d00a59c070801178d198e8905ef670118c15b0906d3a00a662d3a2736bf)


def a0(P, Q): 
    if P[2] == 0 or Q[2] == 0 or P == -Q: 
        return 0 
    if P == Q: 
        a = P.curve().a4() 
        return (3*P[0]^2+a)/(2*P[1]) 
    return (P[1]-Q[1])/(P[0]-Q[0]) 

def add_augmented(PP, QQ):
    (P, u), (Q, v) = PP, QQ
    return [P+Q, u + v + a0(P,Q)]

def scalar_mult(n, PP):
    t = n.nbits()
    TT = PP.copy()
    for i in range(1,t):
        bit = (n >> (t-i-1)) & 1
        TT = add_augmented(TT, TT)
        if bit == 1:
            TT = add_augmented(TT, PP)
    return TT

def solve_ecdlp(P,Q,p):
    R1, alpha = scalar_mult(p, [P,0])
    R2, beta  = scalar_mult(p, [Q,0])
    return ZZ(beta*alpha^(-1))
    

nA = solve_ecdlp(G,A,p)
nB = solve_ecdlp(G,B,p)

assert(nA*G == A)
assert(nB*G == B)

print("Alice's private key: {:x}".format(nA))
print("Bob's private key: {:x}".format(nB))
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值