2024春秋杯网络安全联赛夏季赛Crypto(AK)解题思路及用到的软件

2024春秋杯网络安全联赛夏季赛Crypto(AK)

2024春秋杯网络安全联赛夏季赛Crypto解题思路以及用到的软件

所有题用到的软件

1.vm(虚拟机kali)和Ubuntu,正常配置即可B站有很多。

2.Visual Studio Code(里面要配置python,crypto库和Sagemath数学软件系统Sagemath)。

3.随波逐流工作室 (1o1o.xyz)ctf工具。

ezzzecc

原题代码

p = getPrime(256)
a = getPrime(256)
b = getPrime(256)
E = EllipticCurve(GF(p),[a,b])
m = E.random_point()
G = E.random_point()
k = getPrime(18)
K = k * G
r = getPrime(256)
c1 = m + r * K
c2 = r * G

cipher_left = s2n(flag[:len(flag)//2]) * m[0]   #flag的前半部分乘m[0],所以只要用密文的除于m[0]即可得到flag前半部分
cipher_right = s2n(flag[len(flag)//2:]) * m[1]   #flag的后半部分点乘m[1]


p = p的格式为p={p}koZP3YQAklARRNrmYfjxoKIAXegOcG4jMOmKb08uESOkCCn72d6UM2NWgefYPEMq4EJ1M0jKaqt02Guo5Ubccjqg4QZaaHbScREx38UMLQKwG0LcDd8VFX1zkobc1ZQn4L3DhKQrgJZI55todgOdJuHN532bxScAvOF26gJyQclPtRHn3M6SHrRCEXzzmszd68PJlLB6HaabrRrCW9ZoAYSZetM5jDBtNCJLpR0CBZUUk3Oeh2MZQu2vk8DZ1QqNG49hlxGfawp1FXvAZPdMwixzkhEQnbCDcOKzYyT6BZF2Dfd940tazl7HNOswuIpLsqXQ2h56guGngMeYfMXEZV09fsB3TE0N934CLF8TbZnzFzEkOe8TPTK2mWPVSrgmbsGHnxgYWhaRQWg3yosgDfrEa5qfVl9De41PVtTw024gltovypMXK5XMhuhogs0EMN7hkLapLn6lMj


K = (49293150360761418309411209621405185437426003792008480206387047056777011104939 : 43598371886286324285673726736628847559547403221353820773139325027318579443479)
G = (34031022567935512558184471533035716554557378321289293120392294258731566673565 : 74331715224220154299708533566163247663094029276428146274456519014761122295496)
私钥k小于1000000
c1 = (3315847183153421424358678117707706758962521458183324187760613108746362414091 : 61422809633368910312843316855658127170184420570309973276760547643460231548014)
c2 = (12838481482175070256758359669437500951915904121998959094172291545942862161864 : 60841550842604234546787351747017749679783606696419878692095419214989669624971)
cipher_left = 75142205156781095042041227504637709079517729950375899059488581605798510465939
cipher_right = 61560856815190247060747741878070276409743228362585436028144398174723191051815


解题思路(先解析给的条件接着再看要求)

  1. 确定椭圆曲线参数和点

    • 椭圆曲线的参数 ( p )、( a )、( b ) 已经给出。
    • 点 ( G )、( K )、( c1 )、( c2 ) 也已经给出。
  2. 计算私钥 ( k )

    • 私钥 ( k ) 是一个小于 1000000 的素数。
    • 我们知道 ( K = k \cdot G ),所以可以通过遍历所有可能的 ( k ) 值来找到正确的 ( k )。
  3. 计算明文点 ( m )

    • 我们知道 ( c1 = m + r \cdot K ) 和 ( c2 = r \cdot G )。
    • 通过 ( c2 = r \cdot G ),我们可以计算出 ( r )。
    • 然后使用 ( r ) 和 ( K ) 计算 ( r \cdot K )。
    • 最后,通过 ( c1 - r \cdot K ) 计算出 ( m )。
  4. 解密 flag

    • 使用 ( m ) 的坐标 ( m[0] ) 和 ( m[1] ) 来解密 cipher_left 和 cipher_right

脚本如下

#from sage.all import *  # 导入SageMath的所有功能,但在此代码中未使用
from Crypto.Util.number import *  # 导入Crypto库中的实用函数
# 定义椭圆曲线参数
a = 87425770561190618633288232353256495656281438408946725202136726983601884085917
b = 107879772066707091306779801409109036008421651378615140327877558014536331974777
p = 95258468765219141626168727997935766803481277588106799359407486570046359762703
# 打印p的二进制长度
print(len(bin(p)))
# 定义椭圆曲线E
E = EllipticCurve(GF(p), [a, b])
# 打印椭圆曲线E的阶(点的数量)
print(E.order())
# 定义密文部分
cipher_left = 75142205156781095042041227504637709079517729950375899059488581605798510465939
cipher_right = 61560856815190247060747741878070276409743228362585436028144398174723191051815
# 定义椭圆曲线上的点c1和c2
c1 = E(3315847183153421424358678117707706758962521458183324187760613108746362414091, 61422809633368910312843316855658127170184420570309973276760547643460231548014)
c2 = E(12838481482175070256758359669437500951915904121998959094172291545942862161864, 60841550842604234546787351747017749679783606696419878692095419214989669624971)
# 尝试不同的k值来解密
for k in range(1000000):
    m = c1 - k * c2  # 计算m = c1 - k * c2
    flag1 = long_to_bytes(int(cipher_left / m[0]))  # 将cipher_left除以m的x坐标并转换为字节
    flag2 = long_to_bytes(int(cipher_right / m[1]))  # 将cipher_right除以m的y坐标并转换为字节
    if b'flag' in flag1 or b'ctf' in flag1:  # 检查是否包含'flag'或'ctf'
        print(flag1 + flag2)  # 打印解密结果
        break  # 找到结果后退出循环

解密的关键在于找到一个合适的 k 值,这个 k 值的范围是从 0 到 999999。对于每一个 k,我们计算 m = c1 - k * c2

接着,我们把 cipher_left 和 cipher_right 分别除以 m 的 x 坐标和 y 坐标,得到两个字节串 flag1 和 flag2

最后一步,我们检查一下 flag1 里面有没有包含关键字 b'flag' 或者 b'ctf'。如果有的话,我们就把 flag1 和 flag2 拼接起来,输出完整的 flag。

视频讲解: 

2024春秋竞赛ezzzecc视频解题思路

flag 

happy2024

原题代码1

from not2022but2024 import CBC_key  # 从not2022but2024模块导入CBC_key
from Crypto.Util.Padding import pad  # 从Crypto库导入填充函数

flag = b'flag{}'  # 定义一个字节串形式的flag
from Crypto.Cipher import AES  # 从Crypto库导入AES加密模块
from hashlib import sha256  # 从hashlib库导入sha256哈希函数
import random  # 导入随机数生成模块

n = 92409623123098901791792363114697204166734358914220895740223341612682462563324908002852969747447253269353656265717157699071118377228204036796781052853910448495779756732335396395768081489079058079814549547598374174800251028951681229956305213989996252604809845148110414284348919868084631304579378411884754210093
m = 80  # 定义一个整数m
M = random_prime(2^256)  # 生成一个256位的随机素数M
As = [random.randrange(0, M) for i in range(n)]  # 生成n个在0到M之间的随机数
xs = [random_vector(GF(2), m).change_ring(ZZ) for i in range(n)]  # 生成n个随机向量,每个向量有m个元素
Bs = sum([As[_] * vector(Zmod(M), xs[_]) for _ in range(n)]).change_ring(ZZ)  # 计算Bs,它是As和xs的线性组合

IV = sha256(str(int(sum(As))).encode()).digest()[:16]  # 使用sha256哈希函数生成IV,取前16字节
aes = AES.new(CBC_key, AES.MODE_CBC, iv=IV)  # 创建AES加密对象,使用CBC模式和生成的IV
cipher = aes.encrypt(pad(flag, 16))  # 使用AES加密flag,并进行填充
print(cipher)  # 打印加密后的密文
print(Bs)  # 打印Bs的值
print(M)  # 打印M的值

原题代码2

from Crypto.Util.number import *  # 导入Crypto库中的实用函数

CBC_key = b''  # 初始化CBC模式的密钥,目前为空字节串
p,q = getPrime(512),getPrime(512)  # 生成两个512位的素数p和q
n = p * q  # 计算n,即p和q的乘积
N = n**2 + 2024  # 计算N,即n的平方加上2024
hint = (pow(3, 2022, N) * p**2 + pow(5, 2022, N) * q**2) % N 
# 计算hint,使用3的2022次方模N乘以p的平方加上5的2022次方模N乘以q的平方,然后对N取模
c = pow(bytes_to_long(CBC_key), 65537, n)  # 将CBC_key转换为长整数,然后计算其65537次方模n,得到密文c
print('n =', n)  # 打印n的值
print('h =', hint)  # 打印hint的值
print('c =', c)  # 打印密文c的值

解题思路(先解析给的条件接着再看要求)

首先,我们需要从打印的输出中获取加密后的密文。这个密文是使用AES加密算法生成的。接下来,我们需要计算初始化向量(IV)。IV是通过对As列表中的所有元素求和,并将结果转换为字符串后进行SHA-256哈希,然后取前16字节生成的。我们还需要知道用于加密的密钥(CBC_key)。这个密钥是从not2022but2024模块中导入的。最后,我们使用AES解密对象和IV来解密密文。创建AES解密对象时,使用CBC模式和生成的IV。然后,使用解密对象对密文进行解密,并去除填充,得到原始的flag。

  1. 导入必要的模块和定义变量

    • not2022but2024模块导入CBC_key
    • Crypto库导入填充函数pad
    • 定义一个字节串形式的flag:b'flag{}'
    • Crypto库导入AES加密模块。
    • hashlib库导入sha256哈希函数。
    • 导入随机数生成模块random
  2. 定义一些变量

    • n是一个大整数。
    • m是一个整数。
    • M是一个256位的随机素数。
    • As是一个包含n个在0到M之间的随机数的列表。
    • xs是一个包含n个随机向量的列表,每个向量有m个元素。
    • BsAsxs的线性组合。
  3. 生成IV

    • 使用sha256哈希函数对sum(As)进行哈希,取前16字节作为IV。
  4. 创建AES加密对象并加密flag

    • 使用CBC模式和生成的IV创建AES加密对象。
    • 使用AES加密flag,并进行填充。
  5. 打印加密后的密文、Bs和M

    • 打印加密后的密文。
    • 打印Bs的值。
    • 打印M的值。
  6. 获取加密后的密文

    • 从打印的输出中获取加密后的密文。
  7. 获取IV

    • IV是通过sha256(str(int(sum(As))).encode()).digest()[:16]生成的。
    • 需要知道As的值来计算IV。
  8. 获取CBC_key

    • 需要知道CBC_key的值来进行解密。
  9. 解密密文

    • 使用AES解密对象和IV来解密密文。
  10. 解密密文

    • 使用AES解密对象和IV来解密密文。
    • 我们已经获取了加密后的密文、IV和CBC_key,我们可以进行以下步骤来解密flag:
from Crypto.Cipher import AES
from Crypto.Util.Padding import unpad

# 假设我们已经获取了加密后的密文、IV和CBC_key
cipher = b'encrypted_cipher_text'  # 替换为实际的加密后的密文
IV = b'generated_IV_here'  # 替换为实际的IV
CBC_key = b'CBC_key_here'  # 替换为实际的CBC_key

# 创建AES解密对象
aes = AES.new(CBC_key, AES.MODE_CBC, iv=IV)

# 解密密文
decrypted_padded_flag = aes.decrypt(cipher)

# 去除填充
flag = unpad(decrypted_padded_flag, 16)

print(flag)

CopyInsert

请确保替换cipherIVCBC_key为实际的值。这样,我们就可以解密并打印出flag。

脚本如下

from Crypto.Util.number import *  # 导入Crypto库中的实用函数
from Crypto.Cipher import AES  # 导入AES加密模块
from hashlib import sha256  # 导入SHA-256哈希函数
import random  # 导入随机数生成模块
from gmpy2 import *  # 导入gmpy2库,用于大数运算

# 已知参数
n = 104765768221225848380273603921218042896496091723683489832860494733817042387427987244507704052637674086899990536096984680534816330245712225302233334574349506189442333792630084535988347790345154447062755551340749218034086168589615547612330724516560147636445207363257849894676399157463355106007051823518400959497  # RSA模数n
h = 7203581190271819534576999256270240265858103390821370416379729376339409213191307296184376071456158994788217095325108037303267364174843305521536186849697944281211331950784736288318928189952361923036335642517461830877284034872063160219932835448208223363251605926402262620849157639653619475171619832019229733872640947057355464330411604345531944267500361035919621717525840267577958327357608976854255222991975382510311241178822169596614192650544883130279553265361702184320269130307457859444687753108345652674084307125199795884106515943296997989031669214605935426245922567625294388093837315021593478776527614942368270286385  # 提示值h
c = 86362463246536854074326339688321361763048758911466531912202673672708237653371439192187048224837915338789792530365728395528053853409289475258767985600884209642922711705487919620655525967504514849941809227844374505134264182900183853244590113062802667305254224702526621210482746686566770681208335492189720633162  # RSA密文c
q = 11846999515401139806618780458482772585816656222161925595380112630854263318903047176862162285755281915011589524788709945023820217521669415569797208065004797  # 素数q
p = n // q  # 计算素数p

# 计算phi和d
phi = (p - 1) * (q - 1)  # 计算欧拉函数phi(n)
d = inverse(65537, phi)  # 计算RSA私钥d,即65537在模phi下的逆元

# 解密c得到m
m = pow(c, d, n)  # 使用私钥d解密密文c
print(long_to_bytes(m))  # 将解密得到的整数m转换为字节并打印

# AES解密
CBC_key = b'mylove_in_summer'  # AES解密密钥
enc = b'%\x97\xf77\x16.\x83\x99\x06^\xf2h!k\xfaN6\xb0\x19vd]\x04B\x9e&\xc1V\xed\xa3\x08gX\xb2\xe3\x16\xc2y\xf5/\xb1\x1f>\xa1\xa0DO\xc6gy\xf2l\x1e\xe89\xaeU\xf7\x9d\x03\xe5\xcd*{'  # AES加密的密文
sum = 1190342683523422755570459424048363591795982274808192123460316142044766104571627  # 用于生成IV的值
IV = sha256(str(sum).encode()).digest()[:16]  # 使用SHA-256哈希函数生成IV
aes = AES.new(CBC_key, AES.MODE_CBC, iv=IV)  # 创建AES CBC模式的解密对象
cipher = aes.decrypt(enc)  # 解密AES密文
print(cipher)  # 打印解密后的明文

视频讲解 :

2024春秋竞赛happy2024视频解析

flag

Signature

原题代码

import os
import hashlib
from Crypto.Util.number import *
from Crypto.PublicKey import DSA
import random

def gen_proof_key():
    # 定义一个固定的密码字符串
    password = 'happy_the_year_of_loong'
    getin = '' #定义一个空字符串变量 
    # 随机将密码字符串中的字符转换为大写或小写
    for i in password:#password 字符串中的每个字符进行循环。
        if random.randint(0, 1):#生成一个随机整数,如果该整数为 1,则执行下一行代码。
            getin += i.lower()#将当前字符转换为小写并添加到 getin 字符串中。
        else:
            getin += i.upper()#将当前字符转换为大写并添加到 getin 字符串中
    # 计算转换后字符串的SHA-256哈希值
    ans = hashlib.sha256(getin.encode()).hexdigest()#字符串的 SHA-256 哈希值,并将结果存储在 ans 变量中。
    return getin, ans#返回包含转换后的字符串 getin 和其 SHA-256 哈希值 ans 的元组。

def gen_key():
    # 生成一个私钥,范围在2到q-2之间
    pri = random.randint(2, q - 2)
    # 计算公钥,使用离散对数问题
    pub = pow(g, pri, p)#使用离散对数问题计算公钥 pub,即 g 的 pri 次方模 p。
    return pri, pub#返回包含私钥 pri 和公钥 pub 的元组。

def sign(m, pri):
    k = int(hashlib.md5(os.urandom(20)).hexdigest(), 16) # 生成一个随机的k值,用于签名过程
    H = int(hashlib.sha256(m).hexdigest(), 16) # 计算消息的SHA-256哈希值
    r = pow(g, k, p) % q# 计算签名中的r值
    s = pow(k, -1, q) * (H + pri * r) % q# 计算签名中的s值
    return r, s

def verify(pub, m, signature):
    r, s = signature  # 从签名中提取r和s
    if r <= 0 or r >= q or s <= 0 or s >= q:  # 如果r或s不在有效范围内,返回False
        return False
    w = pow(s, -1, q)  # 计算s的模逆w,w * s ≡ 1 (mod q)
    H = int(hashlib.sha256(m).hexdigest(), 16)  # 计算消息m的SHA-256哈希值,并转换为整数
    # 计算u1和u2
    u1 = H * w % q 
    u2 = r * w % q  
    # 计算v值
    v = (pow(g, u1, p) * pow(pub, u2, p) % p) % q  # 计算v = (g^u1 * pub^u2 mod p) mod q
    # 验证签名是否正确
    return v == r  # 如果v等于r,则签名正确,返回True;否则返回False


def login():
    print('Hello sir, Plz login first')# 打印欢迎信息
    # 定义菜单选项
    menu = ''' 
    1. sign
    2. verify
    3. get my key
    '''
    times = 8# 初始化尝试次数
    while True:# 进入循环
        print(menu)# 打印菜单
        if times < 0: # 检查尝试次数是否用完
            print('Timeout!')# 检查尝试次数是否用完
            return False
        choice = int(input('>'))# 获取用户选择
        if choice == 1:# 处理用户选择
            name = input('Username:').encode()# 获取用户名并编码为字节
            if b'admin' in name:# 检查用户名是否包含'admin'
                print('Get out!') # 打印拒绝信息并返回False
                return False
            r, s = sign(name, pri)# 签名用户名
            print(f'This is your signature -- > {r},{s}') # 打印签名结果
            times -= 1 # 减少尝试次数
        elif choice == 2:# 处理用户选择
            print('Sure, Plz input your signature') # 提示用户输入签名
            r = int(input('r:'))# 获取签名参数r
            s = int(input('s:'))# 获取签名参数s
            if verify(pub, b'admin', (r, s)) == True:# 验证签名
                print('login success!')
                return True# 打印登录成功信息并返回True
            else:
                print('you are not admin')# 打印登录失败信息并返回False
                return False
        elif choice == 3:# 处理用户选择
            # 打印密钥信息
            print(f'Oh, your key is {(p, q, g)}')

getin, ans = gen_proof_key()  # 调用函数生成一个随机的字符串及其哈希值
print(f'Your gift --> {ans[:6]}')  # 打印哈希值的前6个字符作为礼物
your_token = input('Plz input your token\n>')  # 提示用户输入token
if your_token != getin:  # 检查用户输入的token是否与生成的字符串匹配
    print('Get out!')  # 如果不匹配,打印拒绝信息
    exit(0)  # 退出程序

key = DSA.generate(1024)# 生成DSA密钥对、
p, q, g = key.p, key.q, key.g# 获取DSA参数
pri, pub = gen_key()pri, pub = key.key# 获取私钥和公钥
if login() == False:# 进行登录过程 
    exit(0)
print(open('/flag', 'r').read())# 如果登录成功,读取并显示flag文件内容
'''

解题思路

生成正确的 token:
运行 gen_proof_key 函数,获取 getin 和 ans。
使用 getin 作为 token 输入。
获取 DSA 密钥对:
生成 DSA 密钥对,获取 p, q, g, pri, pub。
通过 login 函数的验证:
选择选项 1 签名一个非 admin 的用户名,获取签名 (r, s)。
选择选项 3 获取 (p, q, g)。
使用获取的 (p, q, g) 和签名 (r, s) 来伪造一个 admin 的签名。
伪造 admin 的签名:
由于 k 是随机生成的,且 k 的值可以通过 r 和 s 推导出来(如果 k 被重用),可以尝试重用 k 来伪造 admin 的签名。
由于 k 是随机生成的,且 k 的值可以通过 r 和 s 推导出来(如果 k 被重用),你可以尝试重用 k 来伪造 admin 的签名。
计算 k:
     k = (H + pri * r) * inverse(s, q) % q
CopyInsert
使用 k 计算 admin 的签名:
    H_admin = int(hashlib.sha256(b'admin').hexdigest(), 16)
    r_admin = pow(g, k, p) % q
     s_admin = inverse(k, q) * (H_admin + pri * r_admin) % q
CopyInsert
验证 admin 的签名:
选择选项 2,输入伪造的 admin 的签名 (r_admin, s_admin)。
如果验证通过,将成功登录为 admin,并获得 flag。

参考博客

因为我用的是虚拟机 ,题目有容器使用没办法直接做,所以你们可以参考一下这个博主

2024春秋杯网络安全联赛夏季赛Crypto-CSDN博客

import os
import hashlib
from Crypto.Util.number import *
from Crypto.PublicKey import DSA
import random

def gen_proof_key():
    # 定义一个固定的密码字符串
    password = 'happy_the_year_of_loong'
    getin = '' #定义一个空字符串变量 
    # 随机将密码字符串中的字符转换为大写或小写
    for i in password:#password 字符串中的每个字符进行循环。
        if random.randint(0, 1):#生成一个随机整数,如果该整数为 1,则执行下一行代码。
            getin += i.lower()#将当前字符转换为小写并添加到 getin 字符串中。
        else:
            getin += i.upper()#将当前字符转换为大写并添加到 getin 字符串中
    # 计算转换后字符串的SHA-256哈希值
    ans = hashlib.sha256(getin.encode()).hexdigest()#字符串的 SHA-256 哈希值,并将结果存储在 ans 变量中。
    return getin, ans#返回包含转换后的字符串 getin 和其 SHA-256 哈希值 ans 的元组。

def gen_key():
    # 生成一个私钥,范围在2到q-2之间
    pri = random.randint(2, q - 2)
    # 计算公钥,使用离散对数问题
    pub = pow(g, pri, p)#使用离散对数问题计算公钥 pub,即 g 的 pri 次方模 p。
    return pri, pub#返回包含私钥 pri 和公钥 pub 的元组。

def sign(m, pri):
    k = int(hashlib.md5(os.urandom(20)).hexdigest(), 16) # 生成一个随机的k值,用于签名过程
    H = int(hashlib.sha256(m).hexdigest(), 16) # 计算消息的SHA-256哈希值
    r = pow(g, k, p) % q# 计算签名中的r值
    s = pow(k, -1, q) * (H + pri * r) % q# 计算签名中的s值
    return r, s

def verify(pub, m, signature):
    r, s = signature  # 从签名中提取r和s
    if r <= 0 or r >= q or s <= 0 or s >= q:  # 如果r或s不在有效范围内,返回False
        return False
    w = pow(s, -1, q)  # 计算s的模逆w,w * s ≡ 1 (mod q)
    H = int(hashlib.sha256(m).hexdigest(), 16)  # 计算消息m的SHA-256哈希值,并转换为整数
    # 计算u1和u2
    u1 = H * w % q 
    u2 = r * w % q  
    # 计算v值
    v = (pow(g, u1, p) * pow(pub, u2, p) % p) % q  # 计算v = (g^u1 * pub^u2 mod p) mod q
    # 验证签名是否正确
    return v == r  # 如果v等于r,则签名正确,返回True;否则返回False


def login():
    print('Hello sir, Plz login first')# 打印欢迎信息
    # 定义菜单选项
    menu = ''' 
    1. sign
    2. verify
    3. get my key
    '''
    times = 8# 初始化尝试次数
    while True:# 进入循环
        print(menu)# 打印菜单
        if times < 0: # 检查尝试次数是否用完
            print('Timeout!')# 检查尝试次数是否用完
            return False
        choice = int(input('>'))# 获取用户选择
        if choice == 1:# 处理用户选择
            name = input('Username:').encode()# 获取用户名并编码为字节
            if b'admin' in name:# 检查用户名是否包含'admin'
                print('Get out!') # 打印拒绝信息并返回False
                return False
            r, s = sign(name, pri)# 签名用户名
            print(f'This is your signature -- > {r},{s}') # 打印签名结果
            times -= 1 # 减少尝试次数
        elif choice == 2:# 处理用户选择
            print('Sure, Plz input your signature') # 提示用户输入签名
            r = int(input('r:'))# 获取签名参数r
            s = int(input('s:'))# 获取签名参数s
            if verify(pub, b'admin', (r, s)) == True:# 验证签名
                print('login success!')
                return True# 打印登录成功信息并返回True
            else:
                print('you are not admin')# 打印登录失败信息并返回False
                return False
        elif choice == 3:# 处理用户选择
            # 打印密钥信息
            print(f'Oh, your key is {(p, q, g)}')

getin, ans = gen_proof_key()  # 调用函数生成一个随机的字符串及其哈希值
print(f'Your gift --> {ans[:6]}')  # 打印哈希值的前6个字符作为礼物
your_token = input('Plz input your token\n>')  # 提示用户输入token
if your_token != getin:  # 检查用户输入的token是否与生成的字符串匹配
    print('Get out!')  # 如果不匹配,打印拒绝信息
    exit(0)  # 退出程序

key = DSA.generate(1024)# 生成DSA密钥对、
p, q, g = key.p, key.q, key.g# 获取DSA参数
pri, pub = gen_key()pri, pub = key.key# 获取私钥和公钥
if login() == False:# 进行登录过程 
    exit(0)
print(open('/flag', 'r').read())# 如果登录成功,读取并显示flag文件内容
'''

代码实现了一个基于DSA(数字签名算法)的登录系统。主要功能和流程:

生成证明密钥 (gen_proof_key):

生成一个随机的字符串 getin,它是固定密码字符串 'happy_the_year_of_loong' 的随机大小写混合版本。
计算 getin 的 SHA-256 哈希值 ans。
返回 getin 和 ans。
生成密钥对 (gen_key):

生成一个私钥 pri,它是介于 2 和 q - 2 之间的随机整数。
计算公钥 pub,它是 g 的 pri 次方模 p。
返回 pri 和 pub。
签名 (sign):

生成一个随机数 k,它是 20 字节随机数据的 MD5 哈希值的整数表示。
计算消息 m 的 SHA-256 哈希值 H。
计算签名参数 r 和 s。
返回 r 和 s。
验证 (verify):

检查签名参数 r 和 s 是否在有效范围内。
计算 w,它是 s 的模逆。
计算消息 m 的 SHA-256 哈希值 H。
计算 u1 和 u2。
计算 v,它是 g 的 u1 次方和 pub 的 u2 次方模 p 的结果再模 q。
返回 v 是否等于 r。
登录 (login):

提供一个菜单,允许用户选择签名、验证或获取密钥。
用户可以选择签名一个非 admin 的用户名,获取签名 (r, s)。
用户可以选择验证 admin 的签名 (r, s)。
用户可以选择获取密钥 (p, q, g)。
如果验证通过,用户将成功登录为 admin,并获得 flag。
主流程:
生成证明密钥 getin 和 ans。
提示用户输入 token,如果 token 不匹配 getin,则退出。
生成 DSA 密钥对 (p, q, g) 和 (pri, pub)。
调用 login 函数进行登录。
如果登录成功,打印 /flag 文件的内容。
这个系统的主要目的是通过 DSA 签名和验证机制来模拟一个安全的登录过程,确保只有拥有正确签名的人才能以 admin 身份登录并获取 flag

 视频讲解 :

2024春秋竞赛夏季赛Signature解题思路

  • 18
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值