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
解题思路(先解析给的条件接着再看要求)
确定椭圆曲线参数和点:
- 椭圆曲线的参数 ( p )、( a )、( b ) 已经给出。
- 点 ( G )、( K )、( c1 )、( c2 ) 也已经给出。
计算私钥 ( k ):
- 私钥 ( k ) 是一个小于 1000000 的素数。
- 我们知道 ( K = k \cdot G ),所以可以通过遍历所有可能的 ( k ) 值来找到正确的 ( k )。
计算明文点 ( 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 )。
解密 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。
导入必要的模块和定义变量:
- 从
not2022but2024
模块导入CBC_key
。- 从
Crypto
库导入填充函数pad
。- 定义一个字节串形式的flag:
b'flag{}'
。- 从
Crypto
库导入AES加密模块。- 从
hashlib
库导入sha256
哈希函数。- 导入随机数生成模块
random
。定义一些变量:
n
是一个大整数。m
是一个整数。M
是一个256位的随机素数。As
是一个包含n
个在0到M
之间的随机数的列表。xs
是一个包含n
个随机向量的列表,每个向量有m
个元素。Bs
是As
和xs
的线性组合。生成IV:
- 使用
sha256
哈希函数对sum(As)
进行哈希,取前16字节作为IV。创建AES加密对象并加密flag:
- 使用CBC模式和生成的IV创建AES加密对象。
- 使用AES加密flag,并进行填充。
打印加密后的密文、Bs和M:
- 打印加密后的密文。
- 打印Bs的值。
- 打印M的值。
获取加密后的密文:
- 从打印的输出中获取加密后的密文。
获取IV:
- IV是通过
sha256(str(int(sum(As))).encode()).digest()[:16]
生成的。- 需要知道
As
的值来计算IV。获取CBC_key:
- 需要知道
CBC_key
的值来进行解密。解密密文:
- 使用AES解密对象和IV来解密密文。
解密密文:
- 使用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
请确保替换
cipher
、IV
和CBC_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解题思路
相关文章:
2024春秋杯网络安全联赛夏季赛Crypto(AK)解题思路及用到的软件
2024春秋杯网络安全联赛夏季赛Crypto(AK) 2024春秋杯网络安全联赛夏季赛Crypto解题思路以及用到的软件 所有题用到的软件 1.vm(虚拟机kali)和Ubuntu,正常配置即可B站有很多。 2.Visual Studio Code(里面要配置python,crypto库和Sagemath数学软件系统S…...
vue2 使用代码编辑器插件 vue-codemirror
vue 使用代码编辑器插件 vue-codemirror 之前用过一次,当时用的一知半解的,所以也没有成文,前几天又因为项目有需求,所以说有用了一次,当然,依旧是一知半解,但是还是稍微写一下子吧!…...
自动驾驶系列—智能巡航辅助功能中的横向避让功能介绍
自动驾驶系列—智能巡航辅助功能中的车道中央保持功能介绍 自动驾驶系列—智能巡航辅助功能中的车道变换功能介绍 自动驾驶系列—智能巡航辅助功能中的横向避让功能介绍 自动驾驶系列—智能巡航辅助功能中的路口通行功能介绍 文章目录 1. 背景介绍2. 功能定义3. 功能原理4. 传感…...
通过this.$options.data()重置变量时,会影响到引用了props或methods的变量
之前的文章我有提到过通过this.$options.data().具体某个值来将该值进行初始化 但我在项目中遇到了一个问题: 具体情况是:在data中定义一个变量时有用到methods中的一个方法,在后续的方法中我通过this. $options.data.值去重置了另一个数据&…...
[PM]产品运营
生命周期 运营阶段 主要工作 拉新 新用户的定义 冷启动 拉新方式 促活 用户活跃的原因 量化活跃度 运营社区化/内容化 留存 用户流失 培养用户习惯 用户挽回 变现 变现方式 付费模式 广告模式 数据变现 变现指标 传播 营销 认识营销 电商营销中心 拼团活动 1.需求整理 2.…...
流程控制语句
目录 前言 一、SET 语句 二、BEGIN END 语句 三、IF ELSE 语句 四、CASE 语句 五、WHILE 语句 六、GOTO 语句 七、RETURN 语句 前言 T-SQL 提供了用于编写过程性代码的语法结构,可用来进行顺序、分支、循环、存储过程等程序设计,编写结构化的模…...
杰发科技AC7840——SENT数据解析及软件Sent发送的实现
0. 测试环境 AC7840官方Demo板; 图莫斯0503 DSlogic U2Basic 使用引脚 输出脚:PB1 时钟:PB2,其他引脚可以不初始化,不接线 1. 数据解析 以下是SENT数据的格式(1tick以3us为例)&#…...
Java后端开发(十五)-- Ubuntu 开启activemq开机自启动功能
目录 1. 修改Wrapper.conf文件配置内容 2. 在/etc/systemd/system目录下创建activemq.service文件 3. 重启服务器,验证是否生效 4. 系统启动目标问题 操作环境: 1、Ubuntu 22.04.4 LTS (GNU/Linux 6.5.0-28-generic x86_64) 2、jdk17.0.11 3、apache-activemq-6.0.1 1. 修…...
56 网络层
本节重点 理解网络层的作用,深入理解IP协议的基本原理 对整个TCP/IP协议有系统的理解 对TCP/IP协议体系下的其他重要协议和技术有一定的了解 目录 前置认识ip协议基本概念协议头格式网段划分特殊的ip地址ip地址的数量限制私有ip和公有ip路由路由表生成算法 在复杂…...
MAC地址泛洪——华为ensp
首先搭建好网络拓扑,包含客户端、服务端、一台交换机 以及 云。 客户端client1和服务端server1各自配置好IP地址,服务端充当FTP服务器,启动ftp服务 其中要先配置cloud1相关配置,然后才可以进行连线, 第一步进行端口…...
golang 字符编码 gbk/gb2312 utf8编码相互转换,判断字符是否gbk编码函数, 字符编码转换基础原理解析, golang默认编码utf8
虽然golang里面的默认编码都是统一的unicode utf8编码, 但是我们在调用外部系统提供的api时,就可能会遇到别人的接口提供的编码非 utf8编码,而是gbk/gb2312编码, 这时候我们就必须要将别人的gbk编码转换为go语言里面的默认编码ut…...
CentOS(7.x、8)上安装EMQX
EMQX 是一个高度可扩展的分布式 MQTT 消息服务器,适用于 IoT、M2M 和移动应用程序。以下是在 CentOS 系统上安装 EMQX 的基本步骤: 在 CentOS 上安装 EMQ X 步骤 1: 添加 EMQ X YUM 源 首先,你需要添加 EMQ X 的官方 YUM 源到你的 CentOS 系…...
Mojo模型魔法:动态定制特征转换的艺术
标题:Mojo模型魔法:动态定制特征转换的艺术 在机器学习领域,模型的灵活性和可扩展性是至关重要的。Mojo模型(Model-as-a-Service)提供了一种将机器学习模型部署为服务的方式,允许开发者和数据科学家轻松地…...
多任务高斯过程数学原理和Pytorch实现示例
高斯过程其在回归任务中的应用我们都很熟悉了,但是我们一般介绍的都是针对单个任务的,也就是单个输出。本文我们将讨论扩展到多任务gp,强调它们的好处和实际实现。 本文将介绍如何通过共区域化的内在模型(ICM)和共区域化的线性模型(LMC)&…...
【PPT把当前页输出为图片】及【PPT导出图片模糊】的解决方法(sci论文图片清晰度)
【PPT把当前页输出为图片】及【PPT导出图片模糊】的解决方法 内容一:ppt把当前页输出为图片:内容二:ppt导出图片模糊的解决方法:方法:步骤1:打开注册表编辑器步骤2:修改注册表: 该文…...
TeraTerm 使用技巧
参考资料 自分がよく使うTeratermマクロによる自動ログインのやり方をまとめてみたよTera Term マクロでログインを自動化してみたTera Term のススメ 目录 简介一. 常用基础设置1.1 语言变更1.2 log设置 二. 小技巧2.1 指定host别名2.2 新开窗口2.3 设置粘贴多行命令时的行间…...
意得润色打折啦
新注册使用可以减15%,ABSJU202,直接使用哦ㅤ 此外,如果老板经费充足,预算高,完全可以试试他家的投稿套餐,科学深度编辑,从期刊选择,到投稿协助,投稿信都帮你写好…...
微软研发致胜策略 06:学无止境
这是一本老书,作者 Steve Maguire 在微软工作期间写了这本书,英文版于 1994 年发布。我们看到的标题是中译版名字,英文版的名字是《Debugging the Development Process》,这本书详细阐述了软件开发过程中的常见问题及其解决方案&a…...
学习大数据DAY21 Linux基本指令2
目录 思维导图 搜索查看查找类 find 从指定目录查找文件 head 与 tail 查看行 cat 查看内容 more 查看大内容 grep 过滤查找 history 查看已经执行过的历史命令 wc 统计文件 du 查看空间 管道符号 | 配合命令使用 上机练习 4 解压安装类 zip unzip 压缩解压 tar …...
【18】Android 线程间通信(三) - Handler
概述 接下来我们会从native层来分析一下,Handler做了什么,以及之前提到过的应用层的两个native的调用链。 nativeWake 最早接触这个方法还记得是什么时候吗?MessageQueue#enqueueMessage中,在这个方法的末尾,我们看…...
静态路由技术
一、路由的概念 路由是指指导IP报文发送的路径信息。 二、路由表的结构 1、Destination/Mask:IP报文的接收方的IP地址及其子网掩码; 2、proto:协议(Static:静态路由协议,Direct:表示直连路由) 3、pref:优先级(数值和优先级成反比) 4、cost:路由开销(从源到目的…...
SpringBoot缓存注解使用
背景 除了 RedisTemplate 外, 自Spring3.1开始,Spring自带了对缓存的支持。我们可以直接使用Spring缓存技术将某些数据放入本机的缓存中;Spring缓存技术也可以搭配其他缓存中间件(如Redis等)进行使用,将某些数据写入到缓存中间件…...
@RequestBody接收到的参数中如何限制List的长度?
在Spring MVC中,你可以使用Valid注解和自定义的验证注解来限制List的长度,防止DOS攻击。具体步骤如下: 创建自定义注解:首先,创建一个自定义注解来验证List的长度。 import javax.validation.Constraint; import jav…...
Linux C语言 54-目录操作
Linux C语言 54-目录操作 本节关键字:Linux、C语言、目录操作、遍历目录 相关C库函数:opendir、readdir、closedir 遍历目录 #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <dirent.h> #include <…...
Java实战中如何使用多线程(线程池)及其为什么使用?
这个话题在入行之前就想过很多次,很多8古文或者你搜索的结果都是告诉你什么提高高并发或者是一些很高大上的话,既没有案例也没有什么公式去证明,但是面试中总是被问到,也没有实战经历,所以面试时一问到多线程的东西就无…...
kafka集群搭建-使用zookeeper
1.环境准备: 使用如下3台主机搭建zookeeper集群,由于默认的9092客户端连接端口不在本次使用的云服务器开放端口范围内,故端口改为了8093。 172.2.1.69:8093 172.2.1.70:8093 172.2.1.71:8093 2.下载地址 去官网下载,或者使用如…...
【python】Numpy运行报错分析:IndexError与形状不匹配问题
✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,…...
你有多自律就有多自由
当你失去对时间的控制权,生活也就失去了平衡。 真正对自己有要求的人,都是高度自律的人。 追求自己想要的生活,任何时候开始都不会晚,关键在于你能够坚持下去,以高度自律的精神,日复一日、年复一年的坚持下…...
Codeforces Round 959 (Div. 1 + Div. 2 ABCDEFG 题) 文字讲解+视频讲解
Problem A. Diverse Game Statement 给定 n m n\times m nm 的矩形 a a a, a a a 中的每一个数均在 1 ∼ n m 1\sim nm 1∼nm 之间且互不相同。求出 n m n\times m nm 的矩形 b b b, b b b 中的每一个数均在 1 ∼ n m 1\sim nm 1∼nm 之间且互…...
WSL2 Centos7 Docker服务启动失败怎么办?
wsl 安装的CentOS7镜像,安装了Docker之后,发现用systemctl start docker 无法将docker启动起来。 解决办法 1、编辑文件 vim /usr/lib/systemd/system/docker.service将13行注释掉,然后在下面新增14行的内容。然后保存退出。 2、再次验证 可以发现,我们已经可以正常通过s…...
公司网站建设技术方案模板/网站seo优化外包顾问
Pandas库pandas 是基于NumPy 的数据分析包,Pandas 的常用数据结构是 Series(一维数据)与 DataFrame(二维数据)import pandas as pd Pandas库之seriesSeries是带标签的一维数组,可存储整数、浮点数、字符串、…...
在线房屋设计网站/热门国际新闻
在Java语言中字符串比较有两种方式: 和equals()。“”比较的是针对两个String类型变量的引用,当两个String类型的变量指向同一个String对象(即同一个内存堆),则返回true。而equals()方法是对String对象封装的字符串内容进行比较,相…...
武汉网站制作公司选华企加速器/成都网站优化
1. 描述 单元格是组成报表的最小元素,FineReport 将单元格很多属性开放给应用开发人员进行控制,如新增单元格,设置列宽、行高,字体、前景色,背景色、显示位置、边框样式、边框颜色等等。 以下我们将常用的属性设置列…...
做网站步骤详解/成都网站seo设计
【科技犬】华为Mate40 Pro搭载5纳米麒麟9000旗舰芯片,集成150亿晶体管,是目前手机工艺最先进、晶体管数最多、集成度最高和性能最全面的5G SoC,全面领跑5G时代。保持高性能的同时,又大幅降低功耗,华为Mate40系列是迄今…...
典当网站/网络推广工作内容怎么写
汇编语言指令格式要用汇编语言编写正确的程序,一定要了解汇编语言的指令格式。汇编语言的指令格式如下:[标号:]操作码(空格)[操作数1] [,操作数2] [,操作数3] [;注释]下面是一条汇编语言指令:MAIN:MOV P3,#FFH ;该指令的功能是…...
网站建设 小程序开发/福州seo外包公司
年会是遇到抽奖环节如何制作ppt呢,这里有个解决方法,提供参考。步骤就是这样:1、新建ppt.2、添加一个命令控件和一个标签控件(开发工具---控件---命令控件&标签控件)3、点击“命令按钮CommandButton1”右击鼠标&am…...