You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Crib Drag攻击开发中十六进制转ASCII的Python实现问题求助

Crib拖拽攻击开发中的问题与修复方案

遇到的问题

  • 十六进制转ASCII功能执行报错
  • 无法正常获取用户输入并执行攻击逻辑
  • 不清楚如何实现十六进制密文解密为ASCII的代码

原代码

def crib_drag_attack(guess, cp1, cp2):

xor_ciphers = ""
for idx in range(len(cp1)):
    ic1 = ord(cp1[idx])
    ic2 = ord(cp2[idx])
    ic_xor = ic1 ^ ic2
    xor_ciphers += chr(ic_xor)

for idx in range(len(xor_ciphers) - len(guess)+1):
    slide = xor_ciphers[idx: idx + len(guess)]
    results = ""
    for i in range(len(guess)):
        ig = ord(guess[i])
        id = ord(slide[i])
        ir = ig ^ id
        results += chr(ir)
    print(results)


def encrypt(key, plaintext):
idx = 0  # Declare index (idx) variable
ciphertext = ""  # Declare ciphertext variable
for p in plaintext:  # Take one character at a time in message
    ip = ord(p)  # Convert to Decimal value code
    k = key[idx]  # Take byte value of the key at idx
    ik = ord(k)  # Convert to Decimal value code
    inew = ip ^ ik  # XOR bit-by-bit
    ciphertext += chr(inew)  # Convert to character code and Update ciphertext
    print(p, hex(ip), k, hex(ik), hex(inew))  # print every result
    idx += 1  # Increment idx by 1

hexstring = ciphertext.encode("ascii").hex()
print("\n{} --> {}\n".format(ciphertext, hexstring))

trial = bytes.fromhex(hexstring).decode("ascii")
print("Trial: {}".format(trial))

return ciphertext


def decrypt(key, ciphertext):
idx = 0  # Declare index (idx) variable
plaintext = ""  # Declare plaintext variable
for c in ciphertext:  # Take one character at a time in message
    ic = ord(c)  # Convert to Decimal value code
    k = key[idx]  # Take byte value of the key at idx
    ik = ord(k)  # Convert to Decimal value code
    inew = ic ^ ik  # XOR bit-by-bit
    plaintext += chr(inew)  # Convert to character code and Update ciphertext
    print(c, hex(ic), k, hex(ik), hex(inew))  # print every result
    idx += 1  # Increment idx by 1

print("\n{} --> {}\n".format(plaintext, plaintext.encode("ascii").hex()))
return plaintext


if __name__ == '__main__':

# ciphertext1 = encrypt(key, message1)
# plaintext1 = decrypt(key, ciphertext1)
# #
# ciphertext2 = encrypt(key, message2)
# plaintext1 = decrypt(key, ciphertext2)

# place the given ciphertext 1 and 2 below

#

# Insert the hex string below
ciphertextHex1 = ""
ciphertextHex2 = ""

# Convert the hex string to ascii string
quote_h  = "300d04014"
quote = binascii.a2b_hex("%s" % 
(quote_h.strip())).decode("ASCII").replace(';', '\n- ')
print(quote)

guess = input("Guess a word: ")
crib_drag_attack(guess, ciphertext1, ciphertext2)

问题修复与代码优化

1. 十六进制转ASCII错误修复

  • 十六进制字符串必须是偶数长度,原代码中quote_h = "300d04014"长度为9(奇数),会触发binascii.Error,需调整为偶数位的合法十六进制字符串。
  • 必须导入binascii模块,否则无法使用a2b_hex方法。
  • 加密后的密文可能包含非ASCII控制字符,直接用ascii编码会丢失数据,应改用字节对象处理密文,避免编码错误。

2. 用户输入与攻击逻辑修复

  • 原代码中ciphertext1和ciphertext2未赋值,直接调用crib_drag_attack会报错,需先将十六进制密文转换为字节串。
  • 调整crib_drag_attack函数,支持字节输入而非字符串,避免ord()处理非ASCII字符的异常。

3. 十六进制解密为ASCII的实现

  • 先将十六进制字符串转换为字节串,再传入decrypt函数解密,最后将解密后的字节串转换为ASCII(可过滤不可打印字符)。

修复后的完整代码

import binascii

def crib_drag_attack(guess, cp1, cp2):
    # 处理字节形式的密文
    xor_ciphers = bytearray()
    for b1, b2 in zip(cp1, cp2):
        xor_ciphers.append(b1 ^ b2)
    
    guess_bytes = guess.encode('ascii')
    for idx in range(len(xor_ciphers) - len(guess_bytes) + 1):
        slide = xor_ciphers[idx: idx + len(guess_bytes)]
        results = bytearray()
        for g, s in zip(guess_bytes, slide):
            results.append(g ^ s)
        # 转换为ASCII,替换不可打印字符为.
        print(results.decode('ascii', errors='replace'))

def encrypt(key, plaintext):
    key_bytes = key.encode('ascii')
    plaintext_bytes = plaintext.encode('ascii')
    ciphertext = bytearray()
    idx = 0
    for p in plaintext_bytes:
        k = key_bytes[idx % len(key_bytes)]  # 支持密钥循环复用
        ciphertext.append(p ^ k)
        print(f"{chr(p)} {hex(p)} {chr(k)} {hex(k)} {hex(p^k)}")
        idx += 1
    
    hexstring = ciphertext.hex()
    print(f"\n{ciphertext.decode('ascii', errors='replace')} --> {hexstring}\n")
    
    # 验证十六进制转换
    trial = bytes.fromhex(hexstring)
    print(f"Trial: {trial.decode('ascii', errors='replace')}")
    return ciphertext

def decrypt(key, ciphertext):
    key_bytes = key.encode('ascii')
    plaintext = bytearray()
    idx = 0
    for c in ciphertext:
        k = key_bytes[idx % len(key_bytes)]
        plaintext.append(c ^ k)
        print(f"{chr(c) if c >= 32 else '.'} {hex(c)} {chr(k)} {hex(k)} {hex(c^k)}")
        idx += 1
    
    plaintext_str = plaintext.decode('ascii', errors='replace')
    print(f"\n{plaintext_str} --> {plaintext.hex()}\n")
    return plaintext_str

if __name__ == '__main__':
    # 示例密钥与明文(可替换为实际数据)
    key = "secretkey"
    message1 = "Hello, this is message one!"
    message2 = "Hi there, this is message two!"
    
    # 生成密文(实际使用时可直接填入十六进制密文)
    ciphertext1 = encrypt(key, message1)
    ciphertext2 = encrypt(key, message2)
    
    # 从十六进制密文初始化(如果已有十六进制密文)
    # ciphertextHex1 = "your_hex_ciphertext_1"
    # ciphertextHex2 = "your_hex_ciphertext_2"
    # ciphertext1 = bytes.fromhex(ciphertextHex1)
    # ciphertext2 = bytes.fromhex(ciphertextHex2)
    
    # 测试十六进制转ASCII
    quote_h = "300d040104"  # 修正为偶数长度的十六进制字符串
    quote_bytes = binascii.a2b_hex(quote_h.strip())
    quote = quote_bytes.decode('ascii', errors='replace').replace(';', '\n- ')
    print(f"Hex to ASCII test: {quote}")
    
    guess = input("Guess a word: ").strip()
    if guess:
        crib_drag_attack(guess, ciphertext1, ciphertext2)

关键修改说明

  • 改用字节数组bytearray处理密文,避免字符串编码带来的异常。
  • 加密/解密函数支持密钥循环复用(idx % len(key_bytes)),符合流密码的常见使用场景。
  • 处理不可打印字符时用.替换,提升可读性。
  • 新增十六进制密文直接初始化的注释示例,方便实际使用。

内容的提问来源于stack exchange,提问作者Claudio Esteban

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 05:05:23