第九届工业信息安全技能大赛-枫叶杯-密码应用安全②决赛

仅供参考

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是双向认证
upload_323d7035e319311689b09675f44cb504

C、D应该都对
upload_8ae7e568f05795b25a96fefe7065f7be

  • 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算法实现的代码片段。请回答以下问题。

服务器日志:

  1. 开始对用户A进行身份鉴别
  2. 服务端获取用户A发送的公钥值 P:
    046BA3F61FDFC4F8E5A7C023CFF677BE26E6231E06292F028B9A340CCB56E8E875DE90B12C79585C17F8EAA5956A773357722388F83D7D2D2CFB0F58258BE42FC0
  3. 产生挑战的杂凑值 e:8974A2FA36E81570A956B5166939DD675BF63206E36DE3F64CCD2F096AAC289B
  4. 收到签名值(r1, s1):r1:5EC92F735CB3CAD1F9FA05833EAE4217740D32ED5FA2D2907B3317813D861055
    s1:4EEA57B4DADF8191D7F9700BA3954BDD9EA0EF0227BA0BD805948D19C4DBCC5B
  5. 验签成功!身份鉴别完成。
  6. 验收到用户A 发送的文件杂凑值 e2:
    7D57B77F5966E13AC494486F20CEF59B4A8A5403C15A80EA0BC1C10654455435
    和对应签名值(r2, s2):
    r2:52AC43F87F32969C153798DBF6435A4B62A154EA3D8F6F843A27A97E271F3BEF
    s2:84660B9F0B3A176549BB821C9BA220687B069BBA6DB3F32A2513DF132504260D
  7. 验签成功!文件与签名匹配。

基于 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()
posted @ 2025-07-25 23:09  wgf4242  阅读(169)  评论(1)    收藏  举报