第九届工业信息安全技能大赛-枫叶杯-密码应用安全②决赛
仅供参考
1.已知大数是(十进制):
115792089237316195423570985008687907853269984665640564039457584007913129639927
- 请分析该数是素数还是合数? (50/分)
合数
2.测试者在网络中截取了一份电子签章数据,请根据题目提供的数据,回答以下问题:
附件:
- 1).电子印章制章人数字证书序列号(16进制)是: (50/分)
9FF92DD544494884459DC1FCE14F9DD5
- 2).电子签章签章人数字证书公钥(16进制)是: (50/分)
0462458D3426238FDDC270E38A1347F4C8EA3E122E5124014E458FCB9B5C1CC23BC1B84E34ABA1EAD8B91B1D270BE04639E8586EE369E92D59533703DD50F788FD
在线验证参考 https://tool.hiofd.com/sm2-sign-verify/
3. SSL
1.在对某重要信息系统测试时,分别从两个SSL VPN网关采集到2份不同客户端与之间通联的握手数据(见数据包)。通过观察、分析和计算,回答以下问题:(在选择题填写多个答案时,填写时填写ABC,不要填写A,B,C等带有分隔符的符号)
附件:
- 1).关于两份SSL VPN的握手数据,下列描述正确的是?
A. 数据 1 的密钥交换算法标识是 ECC ,认证方式是双向认证
B. 数据 2的密钥交换算法标识是 ECDHE ,认证方式是单向认证
C. 客户端与服务端的密钥交换算法标识是 ECC 时,使用SM2算法的密钥交换协议
D. 客户端与服务端的密钥交换算法标识是 ECDHE 时,使用SM2 算法的密钥交换协议
ABC
参考
https://blog.csdn.net/qq_36472340/article/details/129941520#_32
B不对,数据2是双向认证

C、D应该都对

- 2).SSL VPN握手协议的一个重要功能是“交换必要参数,协商预主密钥 ”。而计算预主密钥所需的重要数据,就包含在双方握手数据的ClientKeyExchange消息和ServerKeyExchange消息中。请根据相关技术规范数据1的ClientKeyExchange消息载荷中存在计算预主密钥所需的重要数据。请填写答案(16进制) (50/分)
30819802207F4B012DC041509AF6ACC7A1F7CE31CCA04084C7B96D4EF66C0F9915CFD256EC02204974F1A904D7DF36DFE4D18B8A68A54201C5C8981B40A9DA62C329D41958AC300420AA4A6384B0424F720DFB59CFF8F243B0DCAF1742212FE31D63A60EE07344E2D20430E6813FC1A1BC3F47F0C46D4409BB11B0A0165298D409076DB4FF76021FADEC79BD3FA1D835D50FBC4819F4641A8FBE98
- 3).当密钥交换算法标识是 ECC 时,下列说法正确的是?
A. 预主密钥的长度是48字节
B. 预主密钥的长度是16字节
C. 预主密钥是客户端产生的
D. 预主密钥是服务端产生的
E. 预主密钥是双方共同产生的
AC
- 4).当密钥交换算法标识是ECDHE时,下列说法正确的是?
A. 根据“GM/T 003.3 SM2 椭圆曲线公钥密码算法第 3部分:密钥交换协议 ”中定义的符号,用户A、B最终计算出的U或V可以表示为:U Or V = [(dA + x1 ∙ rA (dB + x2 ∙ rB)]G, 其中,余因子 h=1。
B. 如果第三方已知双方随机数,不知双方私钥,则可以求出 U 或 V,进而求出预主密钥
C. 如果第三方已知双方私钥,不知随机数,则可以求出 U 或 V ,进而求出预主密钥
D. 如果已知 U 或 V ,以及双方随机数和一方私钥,则可以求出另一方私钥
E. 如果不检测证书,可以完成中间人攻击
(100/分)
ABE
4.某公司信息系统前端利用智能密码钥匙对用户银行卡号进行加密,加密程序代码片段如下所示,该程序通过 GM/T 0016-2012《智能密码钥匙密码应用接口规范》定义的接口进行加密操作。
void Encrypt(BYTE * pbData, //明文
ULONG uIDataLen, //明文长度 BYTE * pbEncryptedData, //密文
ULONG * pulEncryptedLen, //密文长度 DEVHANDLE hDev, //设备句柄
HANDLE hKey //加密密钥句柄 )
{
//加密参数EncryptParam
BLOCKCIPHERPARAM EncryptParam={ BYTEIV[MAX_IV_LEN]={ 0,};
ULONG IVLen = 16;
ULONG PaddingType = 0; ULONG FeedBitLen = 128;
}
//IV
//IV长度
//填充类型
//反馈的比特长度
//初始化完成后,hKey存储“密钥、工作模式、IV、填充类型和反馈的比特长度”等数据。
SKF_EncryptoInit(hKey,EncryptParam); //使用加密参数EncryptParam,初始化hKey
//数据加密
SKF_EncryptUpdate(hKey, pbData, ulDataLen, pbEncryptedData, pulEncryptedLen);
SKF_EncryptFinal(hKey, pbEncryptedData + *pulEncryptedLen, ulEncryptedDataLen);
}
MY_main_fun( ) {
...
BYTE * pbKey; //加密密钥
DEVHANDLE hDev, //设备句柄 HANDLE hKey, //加密密钥句柄,
...
SKF_SetSymmKey(hDev, pbKey, 0x00000408, &hKey);
...
BYTE *CardNumber = "9558 8010 0115 5233 584";
Encrypt(CardNumber,24,enCardNumber,&cLen, hDev, hKey);
...
}
请根据上述代码回答下列问题:
- 1).上述代码使用了哪种密码算法银行卡号进行加密?
A:SM1
B:SM2
C:SM3
D:SM4
E:SM9
F:SSF33 (50/分)
D,只有sm4是对称加密,其他都是非对称。代码是个对称加密算法。
- 2).加密算法的加密模式是?
A:ECB
B:OFB
C:CFB
D:CBC
E:MAC (50/分)
0x00000408 OFB
CBC模式特点:不需要"反馈比特长度"这个概念
CFB模式特点:反馈长度决定了每次加密的数据量
- 3).该公司的一个内部工作人员Eve的银行卡号为:6228 4800 1030 1477 914,卡号数据用UTF-8格式存储(见代码 BYTE CardNumber * = “6228 4800 1030 1477 914”;),
其转换为16进制是:0x3632323820343830302031303330203134373720393134。如果Eve获取了如下加密数据信息:
| 姓名 | 银行卡加密数据信息 |
|---|---|
| Eve | ef3af79bd4862c3ec21f103e8e887c935d8b4ad844b140 |
| Bob | ef3af79bd4862c3ec21f103e8e887c92588d4dd844b14c |
求取Bob的卡号是? (100/分)
# -*- coding: utf-8 -*-
# 1. 定义已知数据
p_eve_str = "6228 4800 1030 1477 914"
c_eve_hex = "ef3af79bd4862c3ec21f103e8e887c935d8b4ad844b140"
c_bob_hex = "ef3af79bd4862c3ec21f103e8e887c92588d4dd844b14c"
# 2. 将数据转换为字节串 (bytes)
# Eve的明文,UTF-8编码
p_eve_bytes = p_eve_str.encode('utf-8')
# Eve和Bob的密文,从16进制字符串转换
c_eve_bytes = bytes.fromhex(c_eve_hex)
c_bob_bytes = bytes.fromhex(c_bob_hex)
# 3. 执行异或运算: P_bob = C_bob XOR C_eve XOR P_eve
# 我们使用列表推导式和zip函数来对三个字节串进行逐字节的异或操作
p_bob_bytes = bytes([b_bob ^ b_eve ^ p_eve for b_bob, b_eve, p_eve in zip(c_bob_bytes, c_eve_bytes, p_eve_bytes)])
# 4. 将结果字节串解码为UTF-8字符串并打印
p_bob_str = p_bob_bytes.decode('utf-8')
print(f"计算出的Bob的银行卡号是: {p_bob_str}")
# 6228 4800 1030 0110 918
5.已知同一网络管理中心两个用户A和B的公钥信息(数据为10进制整数)
# A用户公钥:
N=149246565442763940835722636804636671495647683848506669719961869915298101083628798493531285477223116007709554452539893432994503330326222995286026708038549027066361007538288404414093090571014304312231064397282794931931722856172212350001014197754976847189976206272816298245852465051772886548495540633832272442283
E= 2^16+1
# B用户公钥:
N= 98931160587985373474392503750103526965234466159358081114879861121504177434642036801035094404162157997948803156728602180847466792629834151373662865607322327255047396266103072083670332782258386690173078828511402022500844759416392350318980777131166630835592279386987343477713492786892338159045094588897467971029
E= 2^16+1
- 1.求出用户A的私钥是? (150/分)
import gmpy2
N = 149246565442763940835722636804636671495647683848506669719961869915298101083628798493531285477223116007709554452539893432994503330326222995286026708038549027066361007538288404414093090571014304312231064397282794931931722856172212350001014197754976847189976206272816298245852465051772886548495540633832272442283
# yafu 分解n: N = p^2 * q
p = 1571007745962441239
q = 60471075523197466700534406162244788455356693436386728998436988378898021001389024945514402672168584019417463013487107038419146754280470507414771677271569136818122773501817779878970706951223404393904366440008429187423278906291416192661336341697364220027777664253450658134523
E = 2 ** 16 + 1
phi_n = p * (p - 1) * (q - 1)
d = gmpy2.invert(E, phi_n)
print(f'd={int(d)}')
# 138329251029034134190055740297279753306849806801788132449703806121394625094015408384732482649387442234385186797036266211674654367261586084332141910957657835253532291335895927862742250358489887602307741988486656258534822586397293093013061619182101367261799254101085896192937959046797771948070593835439440056829
2).A发送给B的加密m的信息为?
C=15434497739817129826892972678577155555036341892868648122659415948204838147059702144404601636982234433122059666206684850918226163770542287807656715110890111159910422409780841855049818811894334559698477858351975110721219752041716568187457997856616412925296863810764200732838213602563614824286517459572169641985
求解明文是? (100/分)
import gmpy2
N = 149246565442763940835722636804636671495647683848506669719961869915298101083628798493531285477223116007709554452539893432994503330326222995286026708038549027066361007538288404414093090571014304312231064397282794931931722856172212350001014197754976847189976206272816298245852465051772886548495540633832272442283
# yafu 分解n: N = p^2 * q
p = 1571007745962441239
q = 60471075523197466700534406162244788455356693436386728998436988378898021001389024945514402672168584019417463013487107038419146754280470507414771677271569136818122773501817779878970706951223404393904366440008429187423278906291416192661336341697364220027777664253450658134523
E = 2 ** 16 + 1
phi_n = p * (p - 1) * (q - 1)
d = gmpy2.invert(E, phi_n)
print(f'd={int(d)}')
c = 15434497739817129826892972678577155555036341892868648122659415948204838147059702144404601636982234433122059666206684850918226163770542287807656715110890111159910422409780841855049818811894334559698477858351975110721219752041716568187457997856616412925296863810764200732838213602563614824286517459572169641985
m = gmpy2.powmod(c, d, N)
print(m)
assert gmpy2.powmod(m, E, N) == c
6.某信息系统基于 OpenSSL 实现了 SM2 算法,部署在客户端和服务器进行身份鉴别(两端均为Windows 平台)以及用户对数据摘要进行签名。测试人员采集到服务器日志,以及部分SM2算法实现的代码片段。请回答以下问题。
服务器日志:
- 开始对用户A进行身份鉴别
- 服务端获取用户A发送的公钥值 P:
046BA3F61FDFC4F8E5A7C023CFF677BE26E6231E06292F028B9A340CCB56E8E875DE90B12C79585C17F8EAA5956A773357722388F83D7D2D2CFB0F58258BE42FC0 - 产生挑战的杂凑值 e:8974A2FA36E81570A956B5166939DD675BF63206E36DE3F64CCD2F096AAC289B
- 收到签名值(r1, s1):r1:5EC92F735CB3CAD1F9FA05833EAE4217740D32ED5FA2D2907B3317813D861055
s1:4EEA57B4DADF8191D7F9700BA3954BDD9EA0EF0227BA0BD805948D19C4DBCC5B - 验签成功!身份鉴别完成。
- 验收到用户A 发送的文件杂凑值 e2:
7D57B77F5966E13AC494486F20CEF59B4A8A5403C15A80EA0BC1C10654455435
和对应签名值(r2, s2):
r2:52AC43F87F32969C153798DBF6435A4B62A154EA3D8F6F843A27A97E271F3BEF
s2:84660B9F0B3A176549BB821C9BA220687B069BBA6DB3F32A2513DF132504260D - 验签成功!文件与签名匹配。
基于 OpenSSL 的 SM2 算法实现代码片段:
//Generate Random Number k
unsigned char randomScalar[32];
DWORD processId = GetCurrentProcessId();
srand(processId);
for (int i = 0; i < 32; i++)
randomScalar[i] = rand() & 0xFF;
BN_bin2bn(randomScalar, 32, k);
//(x1, y1) = [k]G
if (!BN_mod(k, k, n, bn_ctx) || !EC_POINT_mul(group, G, k, NULL, NULL, bn_ctx)) goto err;
if (!EC_POINT_get_affine_coordinates_GFp(group, G, x1, y1, bn_ctx)) goto err;
//r = (e + x1) mod n
if (!BN_bin2bn(digest, digestLength, e))
goto err;
if (!BN_mod_add(r, e, x1, n, bn_ctx)) goto err;
//Test r = 0 or (r + k) mod n = 0
if (BN is zero(r) || !BN_mod_add(tmp1, r, k, n, bn_ctx) || BN is zero(tmp1))
goto err;
//s = (1 + da)^(-1)(k - r * da) mod n
if (!BN_mul(tmp1, r, da, bn_ctx) || //tmp1 = r * da !BN_sub(tmp2, k, tmp1) || //tmp2 = k - r * da !BN_copy(tmp3, da) ||
!BN_add_word(tmp3, 1) || //tmp3 = da + 1
!BN_mod_inverse(tmp1, tmp3, n, bn_ctx) || //tmp1 = (da + 1)^(-1)
!BN_mod_mul(s,tmp1, tmp2, n, bn_ctx) //s = (1 + da)^(-1)(k - r*da) mod n )
goto err;
if (BN_is_zero(s)) goto err;
- 1).请根据上述代码和日志数据,分析其中的密码应用安全漏洞,并利用此漏洞,恢复出用户A签名私钥:(请填写16进制数据) (200/分)
# 4F9C24FE451FEDE595391ED1709A1F021833F6399944A27AABCEE051EB832C0D 错了
# SM2 curve parameter n
n = 0xFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54123
# Signature 1 values from the log
r1 = 0x5EC92F735CB3CAD1F9FA05833EAE4217740D32ED5FA2D2907B3317813D861055
s1 = 0x4EEA57B4DADF8191D7F9700BA3954BDD9EA0EF0227BA0BD805948D19C4DBCC5B
# Signature 2 values from the log
r2 = 0x52AC43F87F32969C153798DBF6435A4B62A154EA3D8F6F843A27A97E271F3BEF
s2 = 0x84660B9F0B3A176549BB821C9BA220687B069BBA6DB3F32A2513DF132504260D
# Calculate da = (s1 - s2) * modInverse((s2 + r2) - (s1 + r1), n)
# Numerator: (s1 - s2) mod n
numerator = (s1 - s2) % n
# Denominator: ((s2 + r2) - (s1 + r1)) mod n
term_s1_r1 = (s1 + r1) % n
term_s2_r2 = (s2 + r2) % n
denominator = (term_s2_r2 - term_s1_r1) % n
# Modular multiplicative inverse of the denominator
# In Python 3.8+, pow(a, -1, m) can calculate modular inverse
denominator_inv = pow(denominator, -1, n)
# Calculate da
da = (numerator * denominator_inv) % n
# Print the private key in hexadecimal format
print(f"Recovered private key (da): {da:064x}")
# efbc79b999e311b2e5c07ea8688ec57f1069eb367fafadc7b4060281abd60b9a
7.下面是一段代码,开发者调用密码设备接口对数据库中数据进行加密保护,部分代码如下:
typedef struct DB_ENTRY_ st {
char name[16l;
char address[64];
} DB_ENTRY;
typedef struct ciphet_ctx_st {
void *hSession;
void *hKey;
} CIPHER_CTX;
//假设已经获得了会话句柄 ctx->hSession 和密钥句柄ctx->hKey
int Encrypt(void *hSession,void *hKey,
unsigned int entryIndex, //数据库项序号
const unsigned char *plaintext, unsigned int plaintextLen,
unsigned char *cipherlext,unsigned int *ciphertextLen) {
unsigned char iv[l6] = {0};
unsigned int count = entryIndex;
Memcpy(iv+12,&count,4);
unsigned int offset =0;
unsigned char sireamBlock[16];unsigned
unsigned int streamLen:
unsigned int remainingplaintxtLen;
while(remaining > 0)
{
streamLen=sizeof(streamBloek);
ret= SDF _Encrypt(hSession,hKey,
0x00000401,
NULL,
iv,
16,
streamBlock&streamLen);
If (ret !=SDR_OK)
{
SDF_DestroyKey(hSession,hKey);
Return ret;
}
//计算本次处理长度
unsigned int chunk = remaining <? remaining : 16;
for(unsigned int i = 0;i < chunk; i++)
ciphertext[offset + i] = plaintext[offset + i] ^ streamBlock[i];
count++;
memcpy(iv+ 12,&count,4);
offset += chunk;
Remaining=chunk;
}
*ciphertexLen = offset;
SDF DestroyKey(hSession, hKey);
rtum SDR OK:
}
int Encrypt_and_Store_db_entry(DB_ENTRY *entry, int entryindex, CIPHER CTX *ctx) {
DB_ENTRY_ entry_ ct={0}:
Encrypt(ctx->hSessionctx->hKey,
entryIndex,
(unsigned char*)entry,
sizeof(DB_ENTRY),
(unsigned char*)&entry_ct,
sizeof(DB_ENTRY));
Store_db_entrny(&entry_ct,entryIndex) // 向数据库第 entryIndex 项插入数据
return 0;
}
//其他代码 略..
已知数据库内容如下:
表 1-1数据库部分密文
| 序号 | 密文 |
|---|---|
| 1 | 十六进制:288a52de328d9c3ce637b3f7c2e13bfae29d90ad23d54238f4daf91b006665967bc750da8baf946023c6ac06065044e4c0648003243362b44f3806ef6cbd1df1cca29d293a5ab75588360ae96ee616b0 |
| 2 | 十六进制:e09992a33bde7a69ab80a0475f1c36056ed36383d8f0c23878acc568612a2c8db111df3314055b867a38aae96aed59150cc61d2a1e69d5e1c70e0c06025b0b41599f6e9cd46ef531c0046f044c6cfd59 |
| 3 | 十六进制:6cd7618dc0fbfa6927f094343f5072e1a405ec6a455d05d521526f810bc77598bdd7c21908698565ba36a000040b4fa599fbee9ff05d97858f3c69eb20d1e0a8e4da20dca24d147b93d86b3090c767ff |
表 1-2 数据库前两项数据
| No. | name | address |
|---|---|---|
| 1 | fengye_022739 | dalianganjingzhiqu_021195 |
| 2 | fengye_010028 | dalianganjingzhiqu_006925 |
| 3 |
- 1).第三项数据的用户名是: (75/分)
fengye_016829
- 2).第三项数据的地址是: (75/分)
dalianganjingzhiqu_023202
8. 某加密系统对office文档进行加密,现获取其加密密报(请下载附件),并按照要求作答。
附件:
1).请分析密报规律,求取加密算法,最终破译密报。破译后明文内容是? (300/分)
变换算法 x ^ 0x5a, 循环右移1位
答案
03970373
9. 某组织采用口令对消息进行加密,加密算法如下:
int CryptData(unsigned char *pPlain, int LenPlain, char *pPass, unsigned char *pCrypt) {
const int nTimes = 20000;
int i;
unsigned char hash_sha256[32];
unsigned char hash_sha512[64];
unsigned char Key[MaxLenPlain + 64];
if (pPlain == NULL || pCrypt == NULL) return -1;
SHA256_CTX sha256;
SHA256_Init(&sha256);
SHA256_Update(&sha256, pPass, strlen(pPass));
SHA256_Final(hash_sha256, &sha256);
for (i = 0; i < nTimes; i++) {
SHA256_Init(&sha256);
SHA256_Update(&sha256, hash_sha256, 32);
SHA256_Final(hash_sha256, &sha256);
}
SHA512_CTX sha512;
SHA512_Init(&sha512);
SHA512_Update(&sha512, pPass, strlen(pPass));
SHA512_Final(hash_sha512, &sha512);
for (i = 0; i < 64; i++)
Key[i] = hash_sha512[i] ^ hash_sha256[i % 32];
for (i = 0; i < LenPlain; i++)
Key[i + 64] = Key[i] ^ Key[i + 2] ^ Key[i + 5] ^ Key[i + 6];
for (i = 0; i < LenPlain; i++)
pCrypt[i] = pPlain[i] ^ Key[i + 64];
return 0;
}
侦察发现某次对多人发送同一条消息,消息内容为:“Come to the International Convention Center to discuss specific matters.”。
并获取多人加密密报,并根据历史规律,口令为4-8位数字,请根据掌握信息,求取加密口令。
1).给Alice的密报内容为85016bbcec83e126a6ac15846e6af441cebc54890b96c5cb82e214d2f06aead348bda6011e0a4b9cffdb94f03c44faf72bc273233b78bb1dff2ab5c1d207134ed45e6a4c9357accf,Alice的加密口令是? (100/分)
9312
2).给Bob的密报内容为800f48d4fc93d452c9e9aa255a29c122da26e7c4fd273a081842f6631996285ec7027e835ca14d67219168a5e3d8987e96259e05a45af0ec4ac61ee986aaecb7d779421e4c2d6389,Bob的加密口令是? (100/分)
90289
3).给Eve的密报内容为75495d9f3c54e7264e06bfcd4e0df0617f52ddb4cda1f76235244329e6f05a3c735a31fd029130193c4e718d07353df48715d51f993f93053c60b9ae1db6d0b5c33364fa45632b22,Eve的加密口令是? (300/分)
75955414
import hashlib
import binascii
from tqdm import tqdm
def crypt_data(plain_data, password):
"""
实现C代码中的CryptData函数
"""
n_times = 20000
# 计算SHA256哈希
sha256_hash = hashlib.sha256(password.encode()).digest()
# 迭代20000次SHA256
for _ in range(n_times):
sha256_hash = hashlib.sha256(sha256_hash).digest()
# 计算SHA512哈希
sha512_hash = hashlib.sha512(password.encode()).digest()
# 生成密钥
key = bytearray(len(plain_data) + 64)
# 前64字节:SHA512 XOR SHA256
for i in range(64):
key[i] = sha512_hash[i] ^ sha256_hash[i % 32]
# 后面的字节:基于前面的密钥生成
for i in range(len(plain_data)):
key[i + 64] = key[i] ^ key[i + 2] ^ key[i + 5] ^ key[i + 6]
# 加密/解密数据
result = bytearray(len(plain_data))
for i in range(len(plain_data)):
result[i] = plain_data[i] ^ key[i + 64]
return bytes(result)
def decrypt_data(encrypted_hex, password):
"""
解密函数
"""
try:
encrypted_data = binascii.unhexlify(encrypted_hex)
decrypted = crypt_data(encrypted_data, password)
return decrypted.decode('utf-8', errors='ignore')
except:
return None
def brute_force_password(encrypted_hex, target_message):
"""
暴力破解密码(4-8位数字)
"""
print("开始暴力破解密码...")
# 计算总的可能性数量
total_combinations = sum(10**i for i in range(4, 9)) # 4位到8位数字的总组合数
with tqdm(total=total_combinations, desc="破解进度") as pbar:
# 尝试4位到8位数字密码
for length in range(4, 9):
print(f"\n正在尝试{length}位数字密码...")
for password_num in range(10**(length-1), 10**length):
password = str(password_num)
# 尝试解密
decrypted = decrypt_data(encrypted_hex, password)
if decrypted and target_message in decrypted:
print(f"\n找到密码: {password}")
print(f"解密结果: {decrypted}")
return password
pbar.update(1)
print("\n未找到匹配的密码")
return None
def test_encryption():
"""
测试加密解密功能
"""
test_message = "Come to the International Convention Center to discuss specific matters."
test_password = "12345"
print("测试加密解密功能:")
print(f"原始消息: {test_message}")
print(f"测试密码: {test_password}")
# 加密
encrypted = crypt_data(test_message.encode(), test_password)
encrypted_hex = binascii.hexlify(encrypted).decode()
print(f"加密结果: {encrypted_hex}")
# 解密
decrypted = decrypt_data(encrypted_hex, test_password)
print(f"解密结果: {decrypted}")
return encrypted_hex
def main():
# Alice的密报
alice_encrypted = "85016bbcec83e126a6ac15846e6af441cebc54890b96c5cb82e214d2f06aead348bda6011e0a4b9cffdb94f03c44faf72bc273233b78bb1dff2ab5c1d207134ed45e6a4c9357accf"
target_message = "Come to the International Convention Center to discuss specific matters."
print("=== 密码破解程序 ===")
print(f"目标消息: {target_message}")
print(f"Alice的密报: {alice_encrypted}")
print()
# 首先测试加密解密功能
print("=== 功能测试 ===")
test_encryption()
print()
# 开始破解Alice的密码
print("=== 开始破解Alice的密码 ===")
alice_password = brute_force_password(alice_encrypted, target_message)
if alice_password:
print(f"\n成功破解Alice的密码: {alice_password}")
# 验证解密结果
decrypted_message = decrypt_data(alice_encrypted, alice_password)
print(f"完整解密消息: {decrypted_message}")
else:
print("\n破解失败,未找到正确的密码")
if __name__ == "__main__":
main()
# 9312
# 90289
# 75955414
爆破只能破解 题目1,2。
算法有漏洞。题目3需要分析算法优化。如下
import hashlib
import time
def solve_for_initial_key(encryption_keystream):
"""
通过逆向计算反推初始密钥流 Key[0...63]。
我们已知:
1. encryption_keystream 包含了 Key[64] 到 Key[64 + len - 1] 的值。
2. Key[i + 64] = Key[i] ^ Key[i + 2] ^ Key[i + 5] ^ Key[i + 6]
通过变换公式得到:
Key[i] = Key[i + 64] ^ Key[i + 2] ^ Key[i + 5] ^ Key[i + 6]
我们可以从 i = 63 倒推计算到 i = 0。
"""
print("[+] 步骤 3: 正在通过逆向计算求解初始密钥...")
# 【修正点】动态计算key数组的大小,防止下标越界
# 大小 = 64字节(待求解) + 已知加密密钥流的长度
key = bytearray(64 + len(encryption_keystream))
# 填充已知部分 (Key[64] 之后)
for i in range(len(encryption_keystream)):
key[i + 64] = encryption_keystream[i]
# 从 i = 63 倒着计算到 i = 0
for i in range(63, -1, -1):
val = key[i + 64] ^ key[i + 2] ^ key[i + 5] ^ key[i + 6]
key[i] = val
print("[+] 求解成功!")
# 返回我们计算出的初始密钥部分 Key[0...63]
return bytes(key[:64])
def main():
# --- 步骤 1: 准备数据 ---
print("[+] 步骤 1: 正在准备明文和密文数据...")
plain_text = b"Come to the International Convention Center to discuss specific matters."
cipher_hex = "85016bbcec83e126a6ac15846e6af441cebc54890b96c5cb82e214d2f06aead348bda6011e0a4b9cffdb94f03c44faf72bc273233b78bb1dff2ab5c1d207134ed45e6a4c9357accf"
cipher_text = bytes.fromhex(cipher_hex)
len_plain = len(plain_text)
print(f" 明文长度: {len_plain} 字节")
print(f" 密文长度: {len(cipher_text)} 字节")
if len_plain < 70: # 逆向计算需要Key[63+6] = Key[69]的值,所以已知流长度至少要到Key[69]
print(f"[!] 错误: 已知明文长度不足70字节,无法进行攻击。需要: 70, 提供: {len_plain}")
return
# --- 步骤 2: 反推加密密钥流 ---
print("[+] 步骤 2: 正在通过 '明文 XOR 密文' 反推加密密钥流...")
encryption_keystream = bytearray(len_plain)
for i in range(len_plain):
encryption_keystream[i] = plain_text[i] ^ cipher_text[i]
print("[+] 反推成功!")
# --- 步骤 3: 求解初始密钥流 Key[0...63] ---
initial_key = solve_for_initial_key(encryption_keystream)
print(f" 解出的初始密钥 Key[0...63] (部分): {initial_key[:16].hex()}...")
# --- 步骤 4: 计算校验指纹 ---
print("[+] 步骤 4: 正在根据漏洞计算校验指纹...")
check_value = bytearray(32)
for i in range(32):
check_value[i] = initial_key[i] ^ initial_key[i + 32]
print(f" 计算出的校验指纹: {check_value.hex()}")
# --- 步骤 5: 快速暴力破解 ---
print("[+] 步骤 5: 开始快速暴力破解 (4-8位数字)...")
start_time = time.time()
found = False
# 【修正点】使用嵌套循环,清晰地测试所有4到8位的密码
for length in range(4, 9): # 测试长度 4, 5, 6, 7, 8
if found: break
print(f"\n 正在测试长度为 {length} 的密码...")
# 遍历该长度下的所有数字组合 (例如 length=4, 0-9999)
for i in range(10 ** length):
password_str = str(i).zfill(length)
fast_hash = hashlib.sha512(password_str.encode('ascii')).digest()
match = True
for j in range(32):
if (fast_hash[j] ^ fast_hash[j + 32]) != check_value[j]:
match = False
break
if match:
end_time = time.time()
print("\n=============================================")
print(f" !!! 成功找到密码 !!!")
print(f" 加密口令是: {password_str}")
print(f" 耗时: {end_time - start_time:.2f} 秒")
print("=============================================")
found = True
break
if i % 200000 == 0 and i > 0:
print(f" 已尝试到: {password_str}", end='\r')
if not found:
end_time = time.time()
print(f"\n[-] 遍历完成,未能找到密码。耗时: {end_time - start_time:.2f} 秒。")
print("[-] 请再次检查明文或密文是否完全准确。")
if __name__ == '__main__':
main()

浙公网安备 33010602011771号