Android与iOS Triple DES加密结果不一致问题求助
解决Android与iOS TripleDES加密结果不一致的问题
我帮你梳理了Android端的TripleDES加密逻辑,咱们一步步对齐iOS端的实现,就能搞定结果不一致的问题。
先明确Android端的核心加密逻辑
从你给出的代码片段,能拆解出几个关键步骤:
- 密钥处理流程:
- 将密钥字符串以
UTF-8编码转为字节数组 - 对该数组做MD5哈希,得到16字节的摘要
- 把16字节摘要扩展为24字节的3DES密钥:通过循环将前8字节复制到16-23的位置(这是3DES兼容16字节密钥的标准操作,重复前8字节作为第三组密钥)
- 将密钥字符串以
- 待确认的细节:
你没贴全Cipher初始化代码,需要确认Android端用的加密模式(比如ECB/CBC)和填充方式(大概率是PKCS5Padding),还有最终加密结果是转成Base64还是十六进制字符串。
iOS端对应实现(基于CommonCrypto)
下面是完全对齐Android逻辑的iOS代码,你可以根据实际情况调整模式和输出格式:
#import <CommonCrypto/CommonCryptor.h> #import <CommonCrypto/CommonDigest.h> // 加密方法:输入明文NSString,输出加密后的字符串(对齐Android输出格式) + (NSString *)tripleDESEncryptString:(NSString *)plainStr withSecretKey:(NSString *)secretKey { // 1. 明文转UTF-8字节数组,对齐Android的编码方式 NSData *plainData = [plainStr dataUsingEncoding:NSUTF8StringEncoding]; if (!plainData) return nil; // 2. 处理密钥:UTF-8编码 -> MD5摘要 -> 扩展为24字节 NSData *keyRawData = [secretKey dataUsingEncoding:NSUTF8StringEncoding]; unsigned char md5Digest[CC_MD5_DIGEST_LENGTH]; CC_MD5(keyRawData.bytes, (CC_LONG)keyRawData.length, md5Digest); // 将16字节MD5摘要扩展为24字节:复制前8字节到末尾 NSMutableData *desKeyData = [NSMutableData dataWithBytes:md5Digest length:CC_MD5_DIGEST_LENGTH]; unsigned char *keyBytes = (unsigned char *)desKeyData.mutableBytes; for (int j = 0; j < 8; j++) { keyBytes[16 + j] = keyBytes[j]; } // 3. 执行加密:对齐Android的模式和填充 // 假设Android用的是ECB模式+PKCS5Padding(和iOS的PKCS7Padding等价,因为块大小是8字节) size_t bufferSize = plainData.length + kCCBlockSize3DES; void *buffer = malloc(bufferSize); size_t encryptedLength = 0; CCCryptorStatus status = CCCrypt(kCCEncrypt, kCCAlgorithm3DES, kCCOptionECBMode | kCCOptionPKCS7Padding, desKeyData.bytes, kCCKeySize3DES, NULL, // ECB模式不需要IV plainData.bytes, plainData.length, buffer, bufferSize, &encryptedLength); if (status != kCCSuccess) { free(buffer); NSLog(@"加密失败:%d", status); return nil; } NSData *encryptedData = [NSData dataWithBytesNoCopy:buffer length:encryptedLength]; // 4. 转成和Android一致的输出格式:如果Android返回Base64就用这个 NSString *encryptedStr = [encryptedData base64EncodedStringWithOptions:0]; // 如果是十六进制输出,替换成下面的代码: // NSString *encryptedStr = [self hexStringFromData:encryptedData]; return encryptedStr; } // 可选:NSData转十六进制字符串的工具方法 + (NSString *)hexStringFromData:(NSData *)data { NSMutableString *hexStr = [NSMutableString stringWithCapacity:data.length * 2]; const unsigned char *bytes = data.bytes; for (NSUInteger i = 0; i < data.length; i++) { [hexStr appendFormat:@"%02x", bytes[i]]; } return hexStr; }
关键注意事项(一定要核对)
- 加密模式对齐:如果Android用的是CBC模式,你必须同步使用相同的IV(初始化向量)。比如Android如果用了固定的全0IV,iOS端也要传入全0的IV数据;如果IV是从密钥派生的,要完全复刻派生逻辑。
- 编码一致性:所有字符串转字节的操作必须用
UTF-8,iOS不要用默认的ASCII编码,否则会导致明文/密钥的字节数组不一致。 - 输出格式统一:Android返回Base64,iOS就转Base64;Android返回十六进制,iOS就转十六进制,别搞混了。
- 密钥扩展细节:Android里的循环是把前8字节复制到16-23位,不是补0,这个细节一定要在iOS代码里实现,否则密钥会不一样。
如果还是有差异,建议把两端的密钥字节数组、明文字节数组、加密后的原始字节数组都转成十六进制对比,就能快速定位哪一步出了问题。
内容的提问来源于stack exchange,提问作者user2583543
相关产品推荐
相关产品推荐

