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 * Gcipher_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}koZP3YQAklARRNrmYfjxoKIAXegOcG4jMOmKb08uESOkCCn72d6UM2NWgefYPEMq4EJ1M0jKaqt02Guo5Ubccjqg4QZaaHbScREx38UMLQKwG0LcDd8VFX1zkobc1ZQn4L3DhKQrgJZI55todgOdJuHN532bxScAvOF26gJyQclPtRHn3M6SHrRCEXzzmszd68PJlLB6HaabrRrCW9ZoAYSZetM5jDBtNCJLpR0CBZUUk3Oeh2MZQu2vk8DZ1QqNG49hlxGfawp1FXvAZPdMwixzkhEQnbCDcOKzYyT6BZF2Dfd940tazl7HNOswuIpLsqXQ2h56guGngMeYfMXEZV09fsB3TE0N934CLF8TbZnzFzEkOe8TPTK2mWPVSrgmbsGHnxgYWhaRQWg3yosgDfrEa5qfVl9De41PVtTw024gltovypMXK5XMhuhogs0EMN7hkLapLn6lMjK = (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 * c2flag1 = 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 randomdef 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, sdef verify(pub, m, signature):r, s = signature  # 从签名中提取r和sif r <= 0 or r >= q or s <= 0 or s >= q:  # 如果r或s不在有效范围内,返回Falsereturn Falsew = pow(s, -1, q)  # 计算s的模逆w,w * s ≡ 1 (mod q)H = int(hashlib.sha256(m).hexdigest(), 16)  # 计算消息m的SHA-256哈希值,并转换为整数# 计算u1和u2u1 = 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;否则返回Falsedef login():print('Hello sir, Plz login first')# 打印欢迎信息# 定义菜单选项menu = ''' 1. sign2. verify3. get my key'''times = 8# 初始化尝试次数while True:# 进入循环print(menu)# 打印菜单if times < 0: # 检查尝试次数是否用完print('Timeout!')# 检查尝试次数是否用完return Falsechoice = int(input('>'))# 获取用户选择if choice == 1:# 处理用户选择name = input('Username:').encode()# 获取用户名并编码为字节if b'admin' in name:# 检查用户名是否包含'admin'print('Get out!') # 打印拒绝信息并返回Falsereturn Falser, 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:'))# 获取签名参数rs = int(input('s:'))# 获取签名参数sif verify(pub, b'admin', (r, s)) == True:# 验证签名print('login success!')return True# 打印登录成功信息并返回Trueelse:print('you are not admin')# 打印登录失败信息并返回Falsereturn Falseelif 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 randomdef 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, sdef verify(pub, m, signature):r, s = signature  # 从签名中提取r和sif r <= 0 or r >= q or s <= 0 or s >= q:  # 如果r或s不在有效范围内,返回Falsereturn Falsew = pow(s, -1, q)  # 计算s的模逆w,w * s ≡ 1 (mod q)H = int(hashlib.sha256(m).hexdigest(), 16)  # 计算消息m的SHA-256哈希值,并转换为整数# 计算u1和u2u1 = 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;否则返回Falsedef login():print('Hello sir, Plz login first')# 打印欢迎信息# 定义菜单选项menu = ''' 1. sign2. verify3. get my key'''times = 8# 初始化尝试次数while True:# 进入循环print(menu)# 打印菜单if times < 0: # 检查尝试次数是否用完print('Timeout!')# 检查尝试次数是否用完return Falsechoice = int(input('>'))# 获取用户选择if choice == 1:# 处理用户选择name = input('Username:').encode()# 获取用户名并编码为字节if b'admin' in name:# 检查用户名是否包含'admin'print('Get out!') # 打印拒绝信息并返回Falsereturn Falser, 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:'))# 获取签名参数rs = int(input('s:'))# 获取签名参数sif verify(pub, b'admin', (r, s)) == True:# 验证签名print('login success!')return True# 打印登录成功信息并返回Trueelse:print('you are not admin')# 打印登录失败信息并返回Falsereturn Falseelif 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.mzph.cn/diannao/49189.shtml

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

相关文章

基于微信小程序+SpringBoot+Vue的青少年科普教学系统平台(带1w+文档)

基于微信小程序SpringBootVue的青少年科普教学系统平台(带1w文档) 基于微信小程序SpringBootVue的青少年科普教学系统平台(带1w文档) 这个工具就是解决上述问题的最好的解决方案。它不仅可以实时完成信息处理&#xff0c;还缩短高校教师成果信息管理流程&#xff0c;使其系统化…

LINUX之MMC子系统分析

目录 1. 概念1.1 MMC卡1.2 SD卡1.3 SDIO 2. 总线协议2.1 协议2.2 一般协议2.3 写数据2.4 读数据2.5 卡模式2.5.1 SD卡模式2.5.2 eMMC模式 2.6 命令2.6.1 命令类2.6.2 详细命令 2.7 应答2.8 寄存器2.8.1 OCR2.8.2 CID2.8.3 CSD2.8.4 RCA2.8.5 扩展CSD 3. 关键结构3.1 struct sdh…

数学建模(7)——Logistic模型

一、马尔萨斯人口模型 import numpy as np import matplotlib.pyplot as plt# 初始人口 N0 100 # 人口增长率 r 0.02 # 时间段&#xff08;年&#xff09; t np.linspace(0, 200, 200)# 马尔萨斯人口模型 N N0 * np.exp(r * t)# 绘图 plt.plot(t, N, labelPopulation) plt.…

【数据结构】堆的实现以及建堆算法和堆排序

【数据结构】堆的实现以及建堆算法和堆排序 &#x1f525;个人主页&#xff1a;大白的编程日记 &#x1f525;专栏&#xff1a;数据结构 文章目录 【数据结构】堆的实现以及建堆算法和堆排序前言一.堆的实现1.1 堆数据的插入1.2堆数据的删除 二.建堆算法和堆排序2.1思路分析2.…

java的转义字符,注释和代码规范

目录 1.Java运行机制 Java开发快速入门 Java开发注意事项和细节说明 Java学习方法 2.Java的转义字符 Java常用的转义字符 代码示例&#xff1a; 转义字符练习 3.初学java易犯错误 4.注释&#xff08;comment&#xff09; 单行注释与多行注释 文档注释 5.Java代码规…

Spark轨迹大数据处理_scalaSpark代码实两个GIS点(经纬度点)之间的方位角计算

终于有时间来搞一搞这个专栏了 首先声明一下 1、我这个代码是基于一个简化方位角模型&#xff0c;忽略了地球的曲率&#xff0c;适用于距离相对较短的距离。因为业务相关&#xff0c;这个方位角两个点的距离计算不会超过1000km。 2、我这个方位角的计算逻辑&#xff1a;是从一…

使用Top进行设备性能分析思路

Top命令 像windows一样&#xff0c;linux也有一个“进程管理”&#xff0c;可以在命令行执行 top &#xff0c;就可以整体的查看当前机器的资源及进程情况。 在性能问题中&#xff0c;Top是使用较多的一个命令&#xff0c;一般用它可以从整体上了解系统的CPU、内存、IO情况&am…

MongoDB教程(十七):MongoDB主键类型ObjectId

&#x1f49d;&#x1f49d;&#x1f49d;首先&#xff0c;欢迎各位来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里不仅可以有所收获&#xff0c;同时也能感受到一份轻松欢乐的氛围&#xff0c;祝你生活愉快&#xff01; 文章目录 引言一、Object…

【状态机动态规划 状态压缩】1434. 每个人戴不同帽子的方案数

本文涉及知识点 位运算、状态压缩、枚举子集汇总 动态规划汇总 LeetCode 1434. 每个人戴不同帽子的方案数 总共有 n 个人和 40 种不同的帽子&#xff0c;帽子编号从 1 到 40 。 给你一个整数列表的列表 hats &#xff0c;其中 hats[i] 是第 i 个人所有喜欢帽子的列表。 请你…

建投数据人力资源系列产品获得欧拉操作系统及华为鲲鹏技术认证书

近日&#xff0c;经欧拉生态创新中心和华为技术有限公司测评&#xff0c;建投数据自主研发的人力资源管理系统、招聘管理系统、绩效管理系统、培训管理系统&#xff0c;完成了基于欧拉操作系统openEuler 22.03、华为鲲鹏Kunpeng 920&#xff08;Taisha 200&#xff09;的兼容性…

ASP.NET MVC

ASP.NET MVC与.NET Framework关系 .NET Framework是一个庞大的代码库&#xff0c;能为多种编程语言提供支持(如C#、VB、F#等)。同时.NET Framework 提供了多种技术框架&#xff0c;ASP.NET MVC是.NET Framework提供的众多技术框架中的一种&#xff0c;用于开发Web应用。 .NET …

B端:小小详情页蕴藏大学问,附大量案例 。

在B端&#xff08;Business-to-Business&#xff0c;即企业与企业之间的商业模式&#xff09;的设计中&#xff0c;详情页是一个非常重要的环节。虽然它可能看起来只是一个简单的页面&#xff0c;但实际上其中蕴藏着许多大学问。 用户需求与体验&#xff1a; 在B端设计中&…

【Docker】Docker-consul容器服务自动发现与注册

目录 一.Consul概述 1.解决了什么问题 2.什么叫微服务或者注册与发现 3.consul的模式 4.相关命令 二.consul 部署 1.consul服务器部署 2.部署docker容器 3.Nginx负载均衡器 3.1.安装启动nginx 3.2.配置nginx负载均衡 3.3.创建配置consul complate模板文件 3.4.添加…

基于Qt的上位机通用框架

0.前言 最近一年多的时间一直在开发设备控制相关的软件&#xff0c;加上之前在聚光的两年时间&#xff0c;前前后后开发这种设备控制类型的上位机软件也有三年的时间了。总结出了一套基于Qt的上位机编程框架&#xff0c;核心思想类似于C#的依赖注入&#xff0c;对象的初始化都…

JavaScript青少年简明教程:流程控制语句

JavaScript青少年简明教程&#xff1a;流程控制语句 JavaScript 提供了一系列的流程控制语句&#xff0c;用于控制代码的执行顺序。 条件语句 条件语句根据表达式的真假来执行不同的代码块。 if 语句 用于在条件为真时执行代码块。 语法&#xff1a; if(条件){ 条件满足执…

微信小程序获取蓝牙并实现内容打印

通过微信小程序如何实现获取蓝牙打印机并实现打印能力&#xff0c;之前做过一个测试Dome&#xff0c;能够获取附近的蓝牙打印机设备并实现打印,今天开放出来供大家参考。 wxml <!--右下角搜索--> <view class"ly-cass-box"><view class"ly-cas…

Hadoop、HDFS、MapReduce 大数据解决方案

本心、输入输出、结果 文章目录 Hadoop、HDFS、MapReduce 大数据解决方案前言HadoopHadoop 主要组件的Web UI端口和一些基本信息MapReduceMapReduce的核心思想MapReduce的工作流程MapReduce的优缺点Hadoop、HDFS、MapReduce 大数据解决方案 编辑 | 简简单单 Online zuozuo 地址…

广义线性模型(1)广义线性模型详解

一 GLM概述 广义线性模型&#xff08;Generalized Linear Models&#xff0c;GLM&#xff09;由 Nelder 和 Wedderburn 于 1972年提出和发表 &#xff0c;旨在解决普通线性回归模型无法处理因变量离散&#xff0c;并发展能够解决非正态因变量的回归建模任务的建模方法。 在广…

数据结构:二叉搜索树(简单C++代码实现)

目录 前言 1. 二叉搜索树的概念 2. 二叉搜索树的实现 2.1 二叉树的结构 2.2 二叉树查找 2.3 二叉树的插入和中序遍历 2.4 二叉树的删除 3. 二叉搜索树的应用 3.1 KV模型实现 3.2 应用 4. 二叉搜索树分析 总结 前言 本文将深入探讨二叉搜索树这一重要的数据结构。二…

【PyTorch】单目标检测项目

对象检测是在图像中查找特定对象位置的过程,用于处理单对象或多对象检测问题。单对象检测在给定图像中仅定位一个对象。对象的位置可以通过边界框定义。单对象检测使用四个数字预测边界框。对于正方形物体&#xff0c;可以固定宽度和高度&#xff0c;并简化问题以仅预测两个数字…