Python与Objective-C AES128 PKCS7加密结果不一致问题排查
AES128 CBC PKCS7加密:Objective-C CCCrypt与Python实现结果不匹配排查
以下是几个核心排查方向,结合你提供的Frida追踪参数逐一验证:
1. Key/IV的字节一致性
CCCrypt直接使用原始字节流作为Key和IV,Python端容易踩的坑是错误地将字符串编码当成原始字节:
- 若Frida追踪到的Key是十六进制字符串,Python需用
bytes.fromhex(key_hex_str)转换,而非key_str.encode('utf-8') - 对比OC端
keyData和Python端key的十六进制输出(比如OC用[keyData description],Python用key.hex()),确保完全一致 - IV同理,CBC模式下必须是16字节,检查OC传递的IV是否和Python端完全相同(包括是否为全0字节等特殊情况)
2. 加密模式与填充的参数匹配
确认CCCrypt的参数是否符合预期:
- 算法必须是
kCCAlgorithmAES128,模式为kCCModeCBC,填充为kCCOptionPKCS7Padding(对应数值0x0001) - Frida追踪时注意
options参数:若该值为0,说明使用的是ECB模式而非CBC,这会直接导致结果不匹配 - Python端需明确指定
AES.MODE_CBC,且填充使用pkcs7风格(pycryptodome的pad函数默认就是PKCS7,但需显式指定避免混淆)
3. 明文的编码一致性
OC端将NSString转NSData时的编码需和Python端对齐:
- 若OC用
[plaintext dataUsingEncoding:NSUTF8StringEncoding],Python端必须用plaintext.encode('utf-8') - 对比OC端
plainData和Python端明文字节的十六进制值,确保完全一致(比如特殊字符、连字符的编码是否相同)
4. 输出结果的编码转换
OC端加密后的NSData转Base64的方式需和Python端对齐:
- OC的
base64EncodedStringWithOptions:0对应标准Base64编码,Python端用base64.b64encode(ciphertext).decode('utf-8')即可,注意不要使用URL-safe的Base64变体
代码示例对比
Objective-C 标准实现(模拟你的逻辑)
NSString *plaintext = @"y_device=y_C9DB602E-0EB7-4FF4-831E-8DA8CEE0BBF5"; NSData *plainData = [plaintext dataUsingEncoding:NSUTF8StringEncoding]; // 替换为Frida追踪到的实际Key/IV的NSData NSData *keyData = [@"your_16_byte_raw_key" dataUsingEncoding:NSUTF8StringEncoding]; NSData *ivData = [@"your_16_byte_raw_iv" dataUsingEncoding:NSUTF8StringEncoding]; size_t bufferSize = plainData.length + kCCBlockSizeAES128; void *buffer = malloc(bufferSize); size_t numBytesEncrypted = 0; CCCryptorStatus status = CCCrypt(kCCEncrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding, keyData.bytes, keyData.length, ivData.bytes, plainData.bytes, plainData.length, buffer, bufferSize, &numBytesEncrypted); NSData *cipherData = [NSData dataWithBytes:buffer length:numBytesEncrypted]; NSString *base64Result = [cipherData base64EncodedStringWithOptions:0]; free(buffer);
Python 对应实现(使用pycryptodome)
from Crypto.Cipher import AES from Crypto.Util.Padding import pad import base64 plaintext = "y_device=y_C9DB602E-0EB7-4FF4-831E-8DA8CEE0BBF5" # 替换为Frida追踪到的实际Key/IV的字节流 key = b"your_16_byte_raw_key" iv = b"your_16_byte_raw_iv" cipher = AES.new(key, AES.MODE_CBC, iv) padded_plain = pad(plaintext.encode('utf-8'), AES.block_size, style='pkcs7') ciphertext = cipher.encrypt(padded_plain) base64_result = base64.b64encode(ciphertext).decode('utf-8') print(base64_result)
最后验证步骤
- 用Frida导出CCCrypt的所有参数(key、iv、明文、options)的十六进制值
- 把这些值直接代入Python代码中替换对应变量
- 运行Python代码对比输出结果
内容的提问来源于stack exchange,提问作者newbieprogrammer095
相关产品推荐
相关产品推荐

