在Objective-C中解密C#加密字符串及byte[]类型转换问题
C# byte[] 对应 Objective-C 类型及跨平台解密指南
嗨,我来帮你梳理清楚这个问题!跨C#和Objective-C的加解密确实容易在字节类型对应上踩坑,咱们一步步来拆解:
一、C# byte[] 在 Objective-C 中的最佳对应类型
先逐个分析你提到的选项,帮你选最适合的:
- NSData/NSMutableData:这是首推的对应类型!完全贴合C# byte[]的字节流本质,自带
length属性(和C#的.Length直接对应),而且苹果官方的加解密API(比如CommonCrypto)都是基于NSData设计的,处理跨平台加解密时最省心,不用额外做太多适配。 - unsigned char[]:如果需要直接操作底层字节内存,这个是C层面的等价类型——C#的byte是无符号8位整数(0-255),和unsigned char完全匹配。你可以通过NSData的
bytes方法直接拿到指向unsigned char数组的指针,再用length获取长度,很方便。 - const char[]:千万别用!const char是有符号类型,当字节值超过127时会出现符号位错误,直接导致数据失真,完全不适合存储原始字节流。
- NSMutableArray:非常不推荐,把每个字节包装成NSNumber对象会带来额外的性能开销,操作起来还特别繁琐,完全没必要用它来处理原始字节数据。
二、C# byte[] 与 Objective-C 类型的转换方法
1. NSData 转 unsigned char[]
如果拿到的是NSData,要转成可直接遍历的字节数组:
NSData *data = ...; // 你的字节数据 const unsigned char *byteArray = (const unsigned char *)data.bytes; NSUInteger length = data.length; // 遍历示例 for (NSUInteger i = 0; i < length; i++) { unsigned char currentByte = byteArray[i]; // 处理单个字节逻辑 }
2. unsigned char[] 转 NSData
如果是从C层面的字节数组转成NSData(方便调用苹果的加密API):
unsigned char byteArray[] = {0x01, 0x02, 0x03}; NSUInteger length = sizeof(byteArray)/sizeof(byteArray[0]); NSData *data = [NSData dataWithBytes:byteArray length:length];
3. 加密字符串转字节数组(解密前必备步骤)
一般C#加密后会把byte[]转成Base64字符串传输,Objective-C里直接用NSData的Base64解码方法就能搞定:
NSString *encryptedBase64Str = @"从C#获取的加密Base64字符串"; NSData *encryptedData = [[NSData alloc] initWithBase64EncodedString:encryptedBase64Str options:NSDataBase64DecodingIgnoreUnknownCharacters];
如果是Hex字符串格式,需要自己实现转换逻辑或者用成熟的工具类,避免造轮子出错。
三、跨平台解密的核心注意点
除了字节类型对应,你必须确保C#和Objective-C两边的加密参数完全一致,否则肯定解密失败:
- 加密算法:比如AES的话,要确认模式(ECB/CBC)、填充方式(C#的PKCS7和Objective-C的
kCCOptionPKCS7Padding是完全兼容的) - 密钥长度:128/192/256位,密钥的编码方式(比如都是UTF-8转字节)
- 初始化向量(IV):如果是CBC模式,两边的IV必须完全相同;C#如果没指定IV,可能用的是默认值,一定要对齐
给你一个简单的AES解密示例(基于NSData),直接可以复用:
#import <CommonCrypto/CommonCryptor.h> - (NSData *)aesDecryptData:(NSData *)encryptedData withKey:(NSData *)key iv:(NSData *)iv { NSUInteger dataLength = encryptedData.length; size_t bufferSize = dataLength + kCCBlockSizeAES128; void *buffer = malloc(bufferSize); size_t numBytesDecrypted = 0; CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmAES, kCCOptionPKCS7Padding, key.bytes, key.length, iv.bytes, encryptedData.bytes, encryptedData.length, buffer, bufferSize, &numBytesDecrypted); if (cryptStatus == kCCSuccess) { return [NSData dataWithBytesNoCopy:buffer length:numBytesDecrypted]; } free(buffer); return nil; }
四、关于你提到的“超过10个相关方法”
其实如果用NSData配合CommonCrypto的API,核心方法并不多,可能是你考虑了各种边缘情况(比如不同编码转换、异常处理、密钥推导等)才会积累多个方法。建议把通用的字节转换、加解密逻辑封装成一个工具类,避免重复代码,维护起来也更方便。
内容的提问来源于stack exchange,提问作者whyoz
相关产品推荐
相关产品推荐

