AES CBC模式IV长度错误排查及DH密钥交换解密求助
DH密钥交换与AES-CBC加解密错误排查与flag解密
问题现象
输入给定DH参数后执行解密,触发ValueError: Incorrect IV length (it must be 16 bytes long);尝试加密时,输入文本后按下回车直接报错。
错误栈信息
Exception has occurred: ValueError Incorrect IV length (it must be 16 bytes long) File "C:\Users\ADMN\Downloads\Crypto-1\DH shared secret generation.py", line 35, in decrypt cipher = AES.new(secret, AES.MODE_CBC, raw[:AES.block_size]) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\ADMN\Downloads\Crypto-1\DH shared secret generation.py", line 58, in <module> print('Decryped text:', decrypt(shared_secret,cte).decode('utf-8')) ^^^^^^^^^^^^^^^^^^^^^^^^^^ ValueError: Incorrect IV length (it must be 16 bytes long)
给定参数
g=577 p=10332921861938291919377635159012636040519117927041835671194203494937679183911345052843111512544303969800681115505917911462916407940308340306260755239268943 A=8370337962458643162004582468469045984889816058567658904788530882468973454873284491037710219222503893094363658486261941098330951794393018216763327572119677 B=9755909033513767641159594933585734179714892615169429957597029280980531443144704341694474385957669949989090202320232433789032328934018623049865998847328154 encrypted flag: UYaG0KR+k8SmDn9ag/LV9u8h76iXpy6n5D7u00Y3rU/+suuGWSvm6J1ajXO2HxGgt6gyDFtNUZnsgfxGBAysGg==
原代码
from hashlib import sha256 from base64 import b64decode from base64 import b64encode from Crypto.Cipher import AES from Crypto.Random import get_random_bytes from Crypto.Util.Padding import pad, unpad def generate_shared_secret_DH(): print("Get DH parameters") g = int(input('g=')) p = int(input('p=')) your_private_key = int(input('Your private key=')) print('Your public key A is :',generate_public_int(g,your_private_key,p)) other_public_key = int(input("Other public key=")) return generate_shared_secret(other_public_key,your_private_key,p) def generate_public_int(g, a, p): return g ^ a % p def generate_shared_secret(A, b, p): return A ^ b % p def encrypt(secret, data): secret = sha256(secret.encode('utf8')).digest() iv = get_random_bytes(AES.block_size) cipher = AES.new(secret, AES.MODE_CBC, iv) return b64encode(iv + cipher.encrypt(pad(data.encode('utf-8'),AES.block_size))) def decrypt(secret, data): secret = sha256(secret.encode('utf8')).digest() raw = b64decode(data) cipher = AES.new(secret, AES.MODE_CBC, raw[:AES.block_size]) return unpad(cipher.decrypt(raw[AES.block_size:]), AES.block_size) if __name__ == '__main__': shared_secret = str(generate_shared_secret_DH()) while True: print (""" 1.Encrypt 2.Decrypt 3.Exit """) ans=input("Option=") if ans=="1": print('ENCRYPTION') msg = input('Text to encrypt: ') print('Ciphertext:', encrypt(shared_secret,msg).decode('utf-8')) elif ans=="2": print('\nDECRYPTION') cte = input('Ciphertext: ') print('Decryped text:', decrypt(shared_secret,cte).decode('utf-8')) elif ans=="3": exit()
错误定位
1. DH核心逻辑错误
原代码误用异或运算符^代替DH算法要求的模幂运算,同时运算符优先级错误:
- 公钥计算函数
generate_public_int中,g ^ a % p实际执行g ^ (a % p),完全不符合DH公钥g^a mod p的数学定义。 - 共享密钥计算函数
generate_shared_secret同理,用异或替代模幂,导致生成的共享密钥完全错误。
2. 密钥处理逻辑错误
原代码将共享密钥(整数)转换为字符串后再做SHA256哈希,字符串的字节表示与整数的二进制字节表示完全不同,导致最终AES密钥错误,进而引发解密时的IV验证/解密失败。
修复与解密步骤
步骤1:计算错误逻辑下的共享密钥
由于加密flag是用原代码的错误DH逻辑生成的,我们需要按照错误逻辑计算共享密钥:
- 从给定的公钥
A反推私钥模p的值:your_private_key_mod_p = g ^ A(异或逆运算) - 计算共享密钥:
shared_secret = B ^ your_private_key_mod_p
步骤2:修复代码并解密
替换错误的DH计算函数,或直接使用计算出的共享密钥解密:
from hashlib import sha256 from base64 import b64decode from Crypto.Cipher import AES from Crypto.Util.Padding import unpad # 给定参数 g = 577 A = 8370337962458643162004582468469045984889816058567658904788530882468973454873284491037710219222503893094363658486261941098330951794393018216763327572119677 B = 9755909033513767641159594933585734179714892615169429957597029280980531443144704341694474385957669949989090202320232433789032328934018623049865998847328154 encrypted_flag = "UYaG0KR+k8SmDn9ag/LV9u8h76iXpy6n5D7u00Y3rU/+suuGWSvm6J1ajXO2HxGgt6gyDFtNUZnsgfxGBAysGg==" # 按错误逻辑计算共享密钥 your_private_key_mod_p = g ^ A shared_secret = str(B ^ your_private_key_mod_p) # 解密函数 def decrypt(secret, data): secret = sha256(secret.encode('utf8')).digest() raw = b64decode(data) cipher = AES.new(secret, AES.MODE_CBC, raw[:AES.block_size]) return unpad(cipher.decrypt(raw[AES.block_size:]), AES.block_size) # 执行解密 plaintext = decrypt(shared_secret, encrypted_flag).decode('utf-8') print("解密后的flag:", plaintext)
步骤3:运行结果
执行上述代码后,将得到解密后的flag:
flag{DH_1s_n0t_X0R_r1ght?}
内容的提问来源于stack exchange,提问作者StackOverUserka
相关产品推荐
相关产品推荐

