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

news2024/9/22 21:06:13

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解题思路

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1943096.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

uni-app框架+vue 实现上拉加载和下拉刷新功能

前言&#xff1a;哈喽&#xff0c;大家好&#xff0c;我是码喽的自我修养&#xff01;今天给大家分享uni-app框架vue实现上拉加载和下拉刷新功能&#xff01;并提供具体代码帮助大家深入理解&#xff0c;彻底掌握&#xff01;创作不易&#xff0c;如果能帮助到带大家&#xff0…

1. kubernetes核心组件

kubernetes核心组件 一、kubernetes概述1、kubernetes是什么2、kubernetes作用/优势 二、kubernetes核心组件1、节点类型2、核心组件2.1 Master节点的组件2.2 Node节点的组件 3、k8s创建容器的流程 一、kubernetes概述 1、kubernetes是什么 由google公司基于go语言开发的集群…

YOLOv8预测时报错ValueError

【问题描述】执行YOLOv8预测代码时&#xff1a; # 导入训练好的权重文件做预测 from ultralytics import YOLO# Load a pretrained YOLOv8n model model YOLO("/data/yolov8/runs/detect/train6/weights/best.pt")# Run inference on bus.jpg with arguments model…

拆分盘理财模式:深度剖析与理性投资

一、新型理财视角&#xff1a;拆分盘的重新定义 拆分盘&#xff0c;这一投资概念常被包装为“稳健增长”的代名词&#xff0c;尤其在网络金融领域。它本质上并非传统股市中的股票&#xff0c;而是一种基于会员增长与资金流动的理财机制。其核心在于&#xff0c;通过不断吸纳新…

java算法day20

java算法day20 701.二叉搜索树中的插入操作450.删除二叉搜索树中的节点108 将有序数组转换为二叉搜索树 本次的题目都是用递归函数的返回值来完成&#xff0c;多熟悉这样的用法&#xff0c;很方便。 其实我感觉&#xff0c;涉及构造二叉树的题目&#xff0c;用递归函数的返回值…

2024 年 100 大数据科学面试问答

2024 年 100 大数据科学面试问答 一、说明 数据科学是一个快速发展的领域&#xff0c;它正在改变组织根据数据理解和做出决策的方式。因此&#xff0c;公司越来越多地寻求聘请数据科学家来帮助他们理解数据并推动业务成果。这导致了对数据科学家的高需求&#xff0c;这些职位的…

TikTok矩阵:从0到百万粉丝的秘密!

在TikTok这个充满活力与创意的短视频平台上&#xff0c;每一位创作者都怀揣着成为耀眼明星的梦想。如何让自己的作品脱颖而出&#xff0c;吸引并留住万千粉丝的目光&#xff0c;成为了每一位创作者亟待解决的问题。此时&#xff0c;TikTok矩阵策略便如同一盏明灯&#xff0c;照…

【BES2500x系列 -- RTX5操作系统】系统启动流程 -- boot loader概念讲解 --(九)

&#x1f48c; 所属专栏&#xff1a;【BES2500x系列】 &#x1f600; 作  者&#xff1a;我是夜阑的狗&#x1f436; &#x1f680; 个人简介&#xff1a;一个正在努力学技术的CV工程师&#xff0c;专注基础和实战分享 &#xff0c;欢迎咨询&#xff01; &#x1f49…

力扣高频SQL 50题(基础版)第七题

文章目录 力扣高频SQL 50题&#xff08;基础版&#xff09;第七题1068. 产品销售分析 I题目说明思路分析实现过程准备数据&#xff1a;实现方式&#xff1a;结果截图:总结&#xff1a; 力扣高频SQL 50题&#xff08;基础版&#xff09;第七题 1068. 产品销售分析 I 题目说明 …

mysql + Oracle

eg627. 变更性别 Salary 表&#xff1a; ----------------------- | Column Name | Type | ----------------------- | id | int | | name | varchar | | sex | ENUM | | salary | int | ----------------------- id 是这个表…

eclipse 没有war file 选项 不能导入和导出war包

1 eclipse打包war,项目右键 2 安装Web和Java EE插件, 在Eclipse中选择Help菜单&#xff0c;然后选择Install New Software。在Work with下拉菜单中选择All Available Sites&#xff0c;然后选择Web, XML, Java EE and OSGi Enterprise Development进行安装。完成安装后&#xf…

海康视频WEB插件

引入相关依赖 index.html <script src"/video/web-control_1.2.5.min.js"></script> <script src"/video/jquery-1.12.4.min.js" type"text/javascript"></script> <script src"/video/jsencrypt.min.js" …

使用LSTM完成时间序列预测

c 在本教程中&#xff0c;我们将介绍一个简单的示例&#xff0c;旨在帮助初学者入门时间序列预测和 PyTorch 的使用。通过这个示例&#xff0c;你可以学习如何使用 LSTMCell 单元来处理时间序列数据。 我们将使用两个 LSTMCell 单元来学习从不同相位开始的正弦波信号。模型在…

黑马程序员2024最新SpringCloud微服务开发与实战 个人学习心得、踩坑、与bug记录Day4 重置版 全网最全最快

你好,我是Qiuner. 为帮助别人少走弯路和记录自己编程学习过程而写博客 这是我的 github https://github.com/Qiuner ⭐️ gitee https://gitee.com/Qiuner &#x1f339; 如果本篇文章帮到了你 不妨点个赞吧~ 我会很高兴的 &#x1f604; (^ ~ ^) 想看更多 那就点个关注吧 我会…

python3.10.4——windows环境安装

python下载官网&#xff1a;https://www.python.org/downloads/ 如果安装在C盘&#xff0c;需要右键→选择“以管理员身份运行” 勾选2个按钮&#xff0c;选择自定义安装 全部选择&#xff0c;点击Next 更改安装路径 命令行检查python是否安装成功&#xff1a; 出现版本号说明…

通俗地理解主动元数据管理

元数据管理&#xff0c;是企业开展数据管理的核心基础&#xff0c;内容涉及元数据的创建&#xff0c;确定需要捕获哪些元数据&#xff0c;通过哪些工具和流程进行创建&#xff0c;继而将元数据妥善存储&#xff0c;保障安全性和可访问性&#xff0c;并不断更新维护&#xff0c;…

vue3前端开发-小兔鲜项目-使用逻辑函数拆分业务模块

vue3前端开发-小兔鲜项目-使用逻辑函数拆分业务模块&#xff01;其实就是把一些单独的业务代码组成一个js文件。抽离出去后&#xff0c;方便后面的维护。 如图&#xff0c;在一级分类下面新建一个文件夹。composables里面新建2个js文件。 分别封装之前的分类&#xff0c;和ban…

Electron 企业级开发通信与本地存储实用解决方案

背景 之前写了一篇Electron通信的方式&#xff0c;讲述了一下三者之间的通信机制&#xff0c;比较恶心&#xff0c;后来发现有个electron/remote&#xff0c; Electron 渲染进程直接调用主进程的API库electron/remote引用讲解-CSDN博客文章浏览阅读58次。remote是个老库&…

将mars3D导入自己的项目中

文章目录 Mars3D官方文档 一、打开自己的vite项目二、创建场景配置文件1.json文件路径 public\config\config.json2.创建组件定义文件路径 src\components\mars-work\mars-map.vue三、demo中引入四、必要样式 依赖文件 总结 Mars3D官方文档 一、打开自己的vite项目 我创建了一…

【Linux】安装Nacos-单机版

一、摘要 单机模式又称单例模式, 拥有所有Nacos的功能及特性&#xff0c;具有极易部署、快速启动等优点。但无法与其他节点组成集群&#xff0c;无法在节点或网络故障时提供高可用能力。单机模式同样可以使用内置Derby数据库&#xff08;默认&#xff09;和外置数据库进行存储…