第九屆工業(yè)信息安全技能大賽-楓葉杯-密碼應(yīng)用安全②決賽
僅供參考
1.已知大數(shù)是(十進(jìn)制):
115792089237316195423570985008687907853269984665640564039457584007913129639927
- 請(qǐng)分析該數(shù)是素?cái)?shù)還是合數(shù)? (50/分)
合數(shù)
2.測(cè)試者在網(wǎng)絡(luò)中截取了一份電子簽章數(shù)據(jù),請(qǐng)根據(jù)題目提供的數(shù)據(jù),回答以下問題:
附件:
- 1).電子印章制章人數(shù)字證書序列號(hào)(16進(jìn)制)是: (50/分)
9FF92DD544494884459DC1FCE14F9DD5
- 2).電子簽章簽章人數(shù)字證書公鑰(16進(jìn)制)是: (50/分)
0462458D3426238FDDC270E38A1347F4C8EA3E122E5124014E458FCB9B5C1CC23BC1B84E34ABA1EAD8B91B1D270BE04639E8586EE369E92D59533703DD50F788FD
在線驗(yàn)證參考 https://tool.hiofd.com/sm2-sign-verify/
3. SSL
1.在對(duì)某重要信息系統(tǒng)測(cè)試時(shí),分別從兩個(gè)SSL VPN網(wǎng)關(guān)采集到2份不同客戶端與之間通聯(lián)的握手?jǐn)?shù)據(jù)(見數(shù)據(jù)包)。通過觀察、分析和計(jì)算,回答以下問題:(在選擇題填寫多個(gè)答案時(shí),填寫時(shí)填寫ABC,不要填寫A,B,C等帶有分隔符的符號(hào))
附件:
- 1).關(guān)于兩份SSL VPN的握手?jǐn)?shù)據(jù),下列描述正確的是?
A. 數(shù)據(jù) 1 的密鑰交換算法標(biāo)識(shí)是 ECC ,認(rèn)證方式是雙向認(rèn)證
B. 數(shù)據(jù) 2的密鑰交換算法標(biāo)識(shí)是 ECDHE ,認(rèn)證方式是單向認(rèn)證
C. 客戶端與服務(wù)端的密鑰交換算法標(biāo)識(shí)是 ECC 時(shí),使用SM2算法的密鑰交換協(xié)議
D. 客戶端與服務(wù)端的密鑰交換算法標(biāo)識(shí)是 ECDHE 時(shí),使用SM2 算法的密鑰交換協(xié)議
ABC
參考
https://blog.csdn.net/qq_36472340/article/details/129941520#_32
B不對(duì),數(shù)據(jù)2是雙向認(rèn)證

C、D應(yīng)該都對(duì)

- 2).SSL VPN握手協(xié)議的一個(gè)重要功能是“交換必要參數(shù),協(xié)商預(yù)主密鑰 ”。而計(jì)算預(yù)主密鑰所需的重要數(shù)據(jù),就包含在雙方握手?jǐn)?shù)據(jù)的ClientKeyExchange消息和ServerKeyExchange消息中。請(qǐng)根據(jù)相關(guān)技術(shù)規(guī)范數(shù)據(jù)1的ClientKeyExchange消息載荷中存在計(jì)算預(yù)主密鑰所需的重要數(shù)據(jù)。請(qǐng)?zhí)顚懘鸢福?6進(jìn)制) (50/分)
30819802207F4B012DC041509AF6ACC7A1F7CE31CCA04084C7B96D4EF66C0F9915CFD256EC02204974F1A904D7DF36DFE4D18B8A68A54201C5C8981B40A9DA62C329D41958AC300420AA4A6384B0424F720DFB59CFF8F243B0DCAF1742212FE31D63A60EE07344E2D20430E6813FC1A1BC3F47F0C46D4409BB11B0A0165298D409076DB4FF76021FADEC79BD3FA1D835D50FBC4819F4641A8FBE98
- 3).當(dāng)密鑰交換算法標(biāo)識(shí)是 ECC 時(shí),下列說法正確的是?
A. 預(yù)主密鑰的長度是48字節(jié)
B. 預(yù)主密鑰的長度是16字節(jié)
C. 預(yù)主密鑰是客戶端產(chǎn)生的
D. 預(yù)主密鑰是服務(wù)端產(chǎn)生的
E. 預(yù)主密鑰是雙方共同產(chǎn)生的
AC
- 4).當(dāng)密鑰交換算法標(biāo)識(shí)是ECDHE時(shí),下列說法正確的是?
A. 根據(jù)“GM/T 003.3 SM2 橢圓曲線公鑰密碼算法第 3部分:密鑰交換協(xié)議 ”中定義的符號(hào),用戶A、B最終計(jì)算出的U或V可以表示為:U Or V = [(dA + x1 ? rA (dB + x2 ? rB)]G, 其中,余因子 h=1。
B. 如果第三方已知雙方隨機(jī)數(shù),不知雙方私鑰,則可以求出 U 或 V,進(jìn)而求出預(yù)主密鑰
C. 如果第三方已知雙方私鑰,不知隨機(jī)數(shù),則可以求出 U 或 V ,進(jìn)而求出預(yù)主密鑰
D. 如果已知 U 或 V ,以及雙方隨機(jī)數(shù)和一方私鑰,則可以求出另一方私鑰
E. 如果不檢測(cè)證書,可以完成中間人攻擊
(100/分)
ABE
4.某公司信息系統(tǒng)前端利用智能密碼鑰匙對(duì)用戶銀行卡號(hào)進(jìn)行加密,加密程序代碼片段如下所示,該程序通過 GM/T 0016-2012《智能密碼鑰匙密碼應(yīng)用接口規(guī)范》定義的接口進(jìn)行加密操作。
void Encrypt(BYTE * pbData, //明文
ULONG uIDataLen, //明文長度 BYTE * pbEncryptedData, //密文
ULONG * pulEncryptedLen, //密文長度 DEVHANDLE hDev, //設(shè)備句柄
HANDLE hKey //加密密鑰句柄 )
{
//加密參數(shù)EncryptParam
BLOCKCIPHERPARAM EncryptParam={ BYTEIV[MAX_IV_LEN]={ 0,};
ULONG IVLen = 16;
ULONG PaddingType = 0; ULONG FeedBitLen = 128;
}
//IV
//IV長度
//填充類型
//反饋的比特長度
//初始化完成后,hKey存儲(chǔ)“密鑰、工作模式、IV、填充類型和反饋的比特長度”等數(shù)據(jù)。
SKF_EncryptoInit(hKey,EncryptParam); //使用加密參數(shù)EncryptParam,初始化hKey
//數(shù)據(jù)加密
SKF_EncryptUpdate(hKey, pbData, ulDataLen, pbEncryptedData, pulEncryptedLen);
SKF_EncryptFinal(hKey, pbEncryptedData + *pulEncryptedLen, ulEncryptedDataLen);
}
MY_main_fun( ) {
...
BYTE * pbKey; //加密密鑰
DEVHANDLE hDev, //設(shè)備句柄 HANDLE hKey, //加密密鑰句柄,
...
SKF_SetSymmKey(hDev, pbKey, 0x00000408, &hKey);
...
BYTE *CardNumber = "9558 8010 0115 5233 584";
Encrypt(CardNumber,24,enCardNumber,&cLen, hDev, hKey);
...
}
請(qǐng)根據(jù)上述代碼回答下列問題:
- 1).上述代碼使用了哪種密碼算法銀行卡號(hào)進(jìn)行加密?
A:SM1
B:SM2
C:SM3
D:SM4
E:SM9
F:SSF33 (50/分)
D,只有sm4是對(duì)稱加密,其他都是非對(duì)稱。代碼是個(gè)對(duì)稱加密算法。
- 2).加密算法的加密模式是?
A:ECB
B:OFB
C:CFB
D:CBC
E:MAC (50/分)
0x00000408 OFB
CBC模式特點(diǎn):不需要"反饋比特長度"這個(gè)概念
CFB模式特點(diǎn):反饋長度決定了每次加密的數(shù)據(jù)量
- 3).該公司的一個(gè)內(nèi)部工作人員Eve的銀行卡號(hào)為:6228 4800 1030 1477 914,卡號(hào)數(shù)據(jù)用UTF-8格式存儲(chǔ)(見代碼 BYTE CardNumber * = “6228 4800 1030 1477 914”;),
其轉(zhuǎn)換為16進(jìn)制是:0x3632323820343830302031303330203134373720393134。如果Eve獲取了如下加密數(shù)據(jù)信息:
| 姓名 | 銀行卡加密數(shù)據(jù)信息 |
|---|---|
| Eve | ef3af79bd4862c3ec21f103e8e887c935d8b4ad844b140 |
| Bob | ef3af79bd4862c3ec21f103e8e887c92588d4dd844b14c |
求取Bob的卡號(hào)是? (100/分)
# -*- coding: utf-8 -*-
# 1. 定義已知數(shù)據(jù)
p_eve_str = "6228 4800 1030 1477 914"
c_eve_hex = "ef3af79bd4862c3ec21f103e8e887c935d8b4ad844b140"
c_bob_hex = "ef3af79bd4862c3ec21f103e8e887c92588d4dd844b14c"
# 2. 將數(shù)據(jù)轉(zhuǎn)換為字節(jié)串 (bytes)
# Eve的明文,UTF-8編碼
p_eve_bytes = p_eve_str.encode('utf-8')
# Eve和Bob的密文,從16進(jìn)制字符串轉(zhuǎn)換
c_eve_bytes = bytes.fromhex(c_eve_hex)
c_bob_bytes = bytes.fromhex(c_bob_hex)
# 3. 執(zhí)行異或運(yùn)算: P_bob = C_bob XOR C_eve XOR P_eve
# 我們使用列表推導(dǎo)式和zip函數(shù)來對(duì)三個(gè)字節(jié)串進(jìn)行逐字節(jié)的異或操作
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. 將結(jié)果字節(jié)串解碼為UTF-8字符串并打印
p_bob_str = p_bob_bytes.decode('utf-8')
print(f"計(jì)算出的Bob的銀行卡號(hào)是: {p_bob_str}")
# 6228 4800 1030 0110 918
5.已知同一網(wǎng)絡(luò)管理中心兩個(gè)用戶A和B的公鑰信息(數(shù)據(jù)為10進(jìn)制整數(shù))
# 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發(fā)送給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.某信息系統(tǒng)基于 OpenSSL 實(shí)現(xiàn)了 SM2 算法,部署在客戶端和服務(wù)器進(jìn)行身份鑒別(兩端均為Windows 平臺(tái))以及用戶對(duì)數(shù)據(jù)摘要進(jìn)行簽名。測(cè)試人員采集到服務(wù)器日志,以及部分SM2算法實(shí)現(xiàn)的代碼片段。請(qǐng)回答以下問題。
服務(wù)器日志:
- 開始對(duì)用戶A進(jìn)行身份鑒別
- 服務(wù)端獲取用戶A發(fā)送的公鑰值 P:
046BA3F61FDFC4F8E5A7C023CFF677BE26E6231E06292F028B9A340CCB56E8E875DE90B12C79585C17F8EAA5956A773357722388F83D7D2D2CFB0F58258BE42FC0 - 產(chǎn)生挑戰(zhàn)的雜湊值 e:8974A2FA36E81570A956B5166939DD675BF63206E36DE3F64CCD2F096AAC289B
- 收到簽名值(r1, s1):r1:5EC92F735CB3CAD1F9FA05833EAE4217740D32ED5FA2D2907B3317813D861055
s1:4EEA57B4DADF8191D7F9700BA3954BDD9EA0EF0227BA0BD805948D19C4DBCC5B - 驗(yàn)簽成功!身份鑒別完成。
- 驗(yàn)收到用戶A 發(fā)送的文件雜湊值 e2:
7D57B77F5966E13AC494486F20CEF59B4A8A5403C15A80EA0BC1C10654455435
和對(duì)應(yīng)簽名值(r2, s2):
r2:52AC43F87F32969C153798DBF6435A4B62A154EA3D8F6F843A27A97E271F3BEF
s2:84660B9F0B3A176549BB821C9BA220687B069BBA6DB3F32A2513DF132504260D - 驗(yàn)簽成功!文件與簽名匹配。
基于 OpenSSL 的 SM2 算法實(shí)現(xiàn)代碼片段:
//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).請(qǐng)根據(jù)上述代碼和日志數(shù)據(jù),分析其中的密碼應(yīng)用安全漏洞,并利用此漏洞,恢復(fù)出用戶A簽名私鑰:(請(qǐng)?zhí)顚?6進(jìn)制數(shù)據(jù)) (200/分)
# 4F9C24FE451FEDE595391ED1709A1F021833F6399944A27AABCEE051EB832C0D 錯(cuò)了
# 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.下面是一段代碼,開發(fā)者調(diào)用密碼設(shè)備接口對(duì)數(shù)據(jù)庫中數(shù)據(jù)進(jìn)行加密保護(hù),部分代碼如下:
typedef struct DB_ENTRY_ st {
char name[16l;
char address[64];
} DB_ENTRY;
typedef struct ciphet_ctx_st {
void *hSession;
void *hKey;
} CIPHER_CTX;
//假設(shè)已經(jīng)獲得了會(huì)話句柄 ctx->hSession 和密鑰句柄ctx->hKey
int Encrypt(void *hSession,void *hKey,
unsigned int entryIndex, //數(shù)據(jù)庫項(xiàng)序號(hào)
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;
}
//計(jì)算本次處理長度
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) // 向數(shù)據(jù)庫第 entryIndex 項(xiàng)插入數(shù)據(jù)
return 0;
}
//其他代碼 略..
已知數(shù)據(jù)庫內(nèi)容如下:
表 1-1數(shù)據(jù)庫部分密文
| 序號(hào) | 密文 |
|---|---|
| 1 | 十六進(jìn)制:288a52de328d9c3ce637b3f7c2e13bfae29d90ad23d54238f4daf91b006665967bc750da8baf946023c6ac06065044e4c0648003243362b44f3806ef6cbd1df1cca29d293a5ab75588360ae96ee616b0 |
| 2 | 十六進(jìn)制:e09992a33bde7a69ab80a0475f1c36056ed36383d8f0c23878acc568612a2c8db111df3314055b867a38aae96aed59150cc61d2a1e69d5e1c70e0c06025b0b41599f6e9cd46ef531c0046f044c6cfd59 |
| 3 | 十六進(jìn)制:6cd7618dc0fbfa6927f094343f5072e1a405ec6a455d05d521526f810bc77598bdd7c21908698565ba36a000040b4fa599fbee9ff05d97858f3c69eb20d1e0a8e4da20dca24d147b93d86b3090c767ff |
表 1-2 數(shù)據(jù)庫前兩項(xiàng)數(shù)據(jù)
| No. | name | address |
|---|---|---|
| 1 | fengye_022739 | dalianganjingzhiqu_021195 |
| 2 | fengye_010028 | dalianganjingzhiqu_006925 |
| 3 |
- 1).第三項(xiàng)數(shù)據(jù)的用戶名是: (75/分)
fengye_016829
- 2).第三項(xiàng)數(shù)據(jù)的地址是: (75/分)
dalianganjingzhiqu_023202
8. 某加密系統(tǒng)對(duì)office文檔進(jìn)行加密,現(xiàn)獲取其加密密報(bào)(請(qǐng)下載附件),并按照要求作答。
附件:
1).請(qǐng)分析密報(bào)規(guī)律,求取加密算法,最終破譯密報(bào)。破譯后明文內(nèi)容是? (300/分)
變換算法 x ^ 0x5a, 循環(huán)右移1位
答案
03970373
9. 某組織采用口令對(duì)消息進(jìn)行加密,加密算法如下:
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;
}
偵察發(fā)現(xiàn)某次對(duì)多人發(fā)送同一條消息,消息內(nèi)容為:“Come to the International Convention Center to discuss specific matters.”。
并獲取多人加密密報(bào),并根據(jù)歷史規(guī)律,口令為4-8位數(shù)字,請(qǐng)根據(jù)掌握信息,求取加密口令。
1).給Alice的密報(bào)內(nèi)容為85016bbcec83e126a6ac15846e6af441cebc54890b96c5cb82e214d2f06aead348bda6011e0a4b9cffdb94f03c44faf72bc273233b78bb1dff2ab5c1d207134ed45e6a4c9357accf,Alice的加密口令是? (100/分)
9312
2).給Bob的密報(bào)內(nèi)容為800f48d4fc93d452c9e9aa255a29c122da26e7c4fd273a081842f6631996285ec7027e835ca14d67219168a5e3d8987e96259e05a45af0ec4ac61ee986aaecb7d779421e4c2d6389,Bob的加密口令是? (100/分)
90289
3).給Eve的密報(bào)內(nèi)容為75495d9f3c54e7264e06bfcd4e0df0617f52ddb4cda1f76235244329e6f05a3c735a31fd029130193c4e718d07353df48715d51f993f93053c60b9ae1db6d0b5c33364fa45632b22,Eve的加密口令是? (300/分)
75955414
import hashlib
import binascii
from tqdm import tqdm
def crypt_data(plain_data, password):
"""
實(shí)現(xiàn)C代碼中的CryptData函數(shù)
"""
n_times = 20000
# 計(jì)算SHA256哈希
sha256_hash = hashlib.sha256(password.encode()).digest()
# 迭代20000次SHA256
for _ in range(n_times):
sha256_hash = hashlib.sha256(sha256_hash).digest()
# 計(jì)算SHA512哈希
sha512_hash = hashlib.sha512(password.encode()).digest()
# 生成密鑰
key = bytearray(len(plain_data) + 64)
# 前64字節(jié):SHA512 XOR SHA256
for i in range(64):
key[i] = sha512_hash[i] ^ sha256_hash[i % 32]
# 后面的字節(jié):基于前面的密鑰生成
for i in range(len(plain_data)):
key[i + 64] = key[i] ^ key[i + 2] ^ key[i + 5] ^ key[i + 6]
# 加密/解密數(shù)據(jù)
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):
"""
解密函數(shù)
"""
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位數(shù)字)
"""
print("開始暴力破解密碼...")
# 計(jì)算總的可能性數(shù)量
total_combinations = sum(10**i for i in range(4, 9)) # 4位到8位數(shù)字的總組合數(shù)
with tqdm(total=total_combinations, desc="破解進(jìn)度") as pbar:
# 嘗試4位到8位數(shù)字密碼
for length in range(4, 9):
print(f"\n正在嘗試{length}位數(shù)字密碼...")
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"解密結(jié)果: {decrypted}")
return password
pbar.update(1)
print("\n未找到匹配的密碼")
return None
def test_encryption():
"""
測(cè)試加密解密功能
"""
test_message = "Come to the International Convention Center to discuss specific matters."
test_password = "12345"
print("測(cè)試加密解密功能:")
print(f"原始消息: {test_message}")
print(f"測(cè)試密碼: {test_password}")
# 加密
encrypted = crypt_data(test_message.encode(), test_password)
encrypted_hex = binascii.hexlify(encrypted).decode()
print(f"加密結(jié)果: {encrypted_hex}")
# 解密
decrypted = decrypt_data(encrypted_hex, test_password)
print(f"解密結(jié)果: {decrypted}")
return encrypted_hex
def main():
# Alice的密報(bào)
alice_encrypted = "85016bbcec83e126a6ac15846e6af441cebc54890b96c5cb82e214d2f06aead348bda6011e0a4b9cffdb94f03c44faf72bc273233b78bb1dff2ab5c1d207134ed45e6a4c9357accf"
target_message = "Come to the International Convention Center to discuss specific matters."
print("=== 密碼破解程序 ===")
print(f"目標(biāo)消息: {target_message}")
print(f"Alice的密報(bào): {alice_encrypted}")
print()
# 首先測(cè)試加密解密功能
print("=== 功能測(cè)試 ===")
test_encryption()
print()
# 開始破解Alice的密碼
print("=== 開始破解Alice的密碼 ===")
alice_password = brute_force_password(alice_encrypted, target_message)
if alice_password:
print(f"\n成功破解Alice的密碼: {alice_password}")
# 驗(yàn)證解密結(jié)果
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需要分析算法優(yōu)化。如下
import hashlib
import time
def solve_for_initial_key(encryption_keystream):
"""
通過逆向計(jì)算反推初始密鑰流 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 倒推計(jì)算到 i = 0。
"""
print("[+] 步驟 3: 正在通過逆向計(jì)算求解初始密鑰...")
# 【修正點(diǎn)】動(dòng)態(tài)計(jì)算key數(shù)組的大小,防止下標(biāo)越界
# 大小 = 64字節(jié)(待求解) + 已知加密密鑰流的長度
key = bytearray(64 + len(encryption_keystream))
# 填充已知部分 (Key[64] 之后)
for i in range(len(encryption_keystream)):
key[i + 64] = encryption_keystream[i]
# 從 i = 63 倒著計(jì)算到 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("[+] 求解成功!")
# 返回我們計(jì)算出的初始密鑰部分 Key[0...63]
return bytes(key[:64])
def main():
# --- 步驟 1: 準(zhǔn)備數(shù)據(jù) ---
print("[+] 步驟 1: 正在準(zhǔn)備明文和密文數(shù)據(jù)...")
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} 字節(jié)")
print(f" 密文長度: {len(cipher_text)} 字節(jié)")
if len_plain < 70: # 逆向計(jì)算需要Key[63+6] = Key[69]的值,所以已知流長度至少要到Key[69]
print(f"[!] 錯(cuò)誤: 已知明文長度不足70字節(jié),無法進(jìn)行攻擊。需要: 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: 計(jì)算校驗(yàn)指紋 ---
print("[+] 步驟 4: 正在根據(jù)漏洞計(jì)算校驗(yàn)指紋...")
check_value = bytearray(32)
for i in range(32):
check_value[i] = initial_key[i] ^ initial_key[i + 32]
print(f" 計(jì)算出的校驗(yàn)指紋: {check_value.hex()}")
# --- 步驟 5: 快速暴力破解 ---
print("[+] 步驟 5: 開始快速暴力破解 (4-8位數(shù)字)...")
start_time = time.time()
found = False
# 【修正點(diǎn)】使用嵌套循環(huán),清晰地測(cè)試所有4到8位的密碼
for length in range(4, 9): # 測(cè)試長度 4, 5, 6, 7, 8
if found: break
print(f"\n 正在測(cè)試長度為 {length} 的密碼...")
# 遍歷該長度下的所有數(shù)字組合 (例如 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" 耗時(shí): {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[-] 遍歷完成,未能找到密碼。耗時(shí): {end_time - start_time:.2f} 秒。")
print("[-] 請(qǐng)?jiān)俅螜z查明文或密文是否完全準(zhǔn)確。")
if __name__ == '__main__':
main()

浙公網(wǎng)安備 33010602011771號(hào)