CryptoManager.h (头文件定义)
#import <Foundation/Foundation.h>
#import <CommonCrypto/CommonCryptor.h>
#import <CommonCrypto/CommonDigest.h>
#import <Security/Security.h>
NS_ASSUME_NONNULL_BEGIN
#pragma mark - 加密算法枚举
typedef NS_ENUM(NSUInteger, RSAEncryptionPadding) {
RSAEncryptionPaddingPKCS1,
RSAEncryptionPaddingOAEP
};
typedef NS_ENUM(NSUInteger, AESCipherMode) {
AESCipherModeECB,
AESCipherModeCBC,
AESCipherModeCFB,
AESCipherModeOFB,
AESCipherModeCTR
};
typedef NS_ENUM(NSUInteger, AESPaddingOption) {
AESPaddingPKCS7,
AESPaddingNone
};
typedef NS_ENUM(NSUInteger, RSAKeyType) {
RSAKeyTypePublic,
RSAKeyTypePrivate
};
// 定义摘要算法类型
typedef NS_ENUM(NSUInteger, RSASignatureDigestType) {
RSASignatureDigestTypeSHA1,
RSASignatureDigestTypeSHA224,
RSASignatureDigestTypeSHA256,
RSASignatureDigestTypeSHA384,
RSASignatureDigestTypeSHA512
};
#pragma mark - RSAKey 封装类
@interface RSAKey : NSObject
@property (nonatomic, assign) SecKeyRef secKeyRef;
@property (nonatomic, assign) RSAKeyType keyType;
@property (nonatomic, strong) NSData *keyData;
@property (nonatomic, assign) NSUInteger keySize;
- (instancetype)initWithSecKeyRef:(SecKeyRef)secKeyRef keyType:(RSAKeyType)keyType;
- (instancetype)initWithData:(NSData *)keyData keyType:(RSAKeyType)keyType;
@end
#pragma mark - CryptoManager - 核心加密类
@interface CryptoManager : NSObject
#pragma mark - AES 加密/解密
/**
AES加密
@param data 原始数据
@param key 加密密钥
@param iv 初始化向量 (CBC/CFB/OFB/CTR模式需要)
@param mode 加密模式
@param padding 填充方式
@return 加密后的数据
*/
+ (NSData *)AESEncryptData:(NSData *)data
withKey:(NSData *)key
iv:(nullable NSData *)iv
mode:(AESCipherMode)mode
padding:(AESPaddingOption)padding;
/**
AES解密
@param encryptedData 加密数据
@param key 解密密钥
@param iv 初始化向量 (CBC/CFB/OFB/CTR模式需要)
@param mode 加密模式
@param padding 填充方式
@return 解密后的原始数据
*/
+ (NSData *)AESDecryptData:(NSData *)encryptedData
withKey:(NSData *)key
iv:(nullable NSData *)iv
mode:(AESCipherMode)mode
padding:(AESPaddingOption)padding;
#pragma mark - RSA 密钥处理
/**
从PEM格式创建RSA密钥
@param pemString PEM格式的密钥字符串
@param keyType 密钥类型 (公钥/私钥)
@return RSAKey对象
*/
+ (nullable RSAKey *)createRSAKeyFromPEM:(NSString *)pemString keyType:(RSAKeyType)keyType;
/**
从DER格式创建RSA密钥
@param derData DER格式的密钥数据
@param keyType 密钥类型 (公钥/私钥)
@return RSAKey对象
*/
+ (nullable RSAKey *)createRSAKeyFromDER:(NSData *)derData keyType:(RSAKeyType)keyType;
#pragma mark - RSA 加密/解密
/**
RSA加密
@param data 原始数据
@param rsaKey RSAKey对象
@param padding 填充方式
@return 加密后的数据
*/
+ (nullable NSData *)RSAEncryptData:(NSData *)data
withRSAKey:(RSAKey *)rsaKey
padding:(RSAEncryptionPadding)padding;
/**
RSA解密
@param encryptedData 加密数据
@param rsaKey RSAKey对象 (必须是私钥)
@param padding 填充方式
@return 解密后的原始数据
*/
+ (nullable NSData *)RSADecryptData:(NSData *)encryptedData
withRSAKey:(RSAKey *)rsaKey
padding:(RSAEncryptionPadding)padding;
#pragma mark - RSA 签名/验证
/**
RSA签名
@param data 原始数据
@param rsaKey RSAKey对象 (必须是私钥)
@param digestType 摘要算法类型
@return 签名数据
*/
+ (nullable NSData *)RSASignData:(NSData *)data
withRSAKey:(RSAKey *)rsaKey
digestType:(RSASignatureDigestType)digestType;
/**
RSA验证签名
@param data 原始数据
@param signatureData 签名数据
@param rsaKey RSAKey对象 (必须是公钥)
@param digestType 摘要算法类型
@return 验证结果
*/
+ (BOOL)RSAVerifySignature:(NSData *)data
signature:(NSData *)signatureData
withRSAKey:(RSAKey *)rsaKey
digestType:(RSASignatureDigestType)digestType;
#pragma mark - 实用工具方法
/**
生成随机数据
@param length 数据长度
@return 随机数据
*/
+ (NSData *)randomDataOfLength:(size_t)length;
/**
字节数组转十六进制字符串
@param data 二进制数据
@return 十六进制字符串
*/
+ (NSString *)hexStringFromData:(NSData *)data;
/**
十六进制字符串转二进制数据
@param hexString 十六进制字符串
@return 二进制数据
*/
+ (nullable NSData *)dataFromHexString:(NSString *)hexString;
/**
Base64编码字符串转二进制数据
@param base64String Base64编码字符串
@return 二进制数据
*/
+ (nullable NSData *)dataFromBase64EncodedString:(NSString *)base64String;
/**
二进制数据转Base64编码字符串
@param data 二进制数据
@return Base64编码字符串
*/
+ (nullable NSString *)base64EncodedStringFromData:(NSData *)data;
@end
NS_ASSUME_NONNULL_END
CryptoManager.m 实现部分
#import "CryptoManager.h"
@implementation RSAKey
- (instancetype)initWithSecKeyRef:(SecKeyRef)secKeyRef keyType:(RSAKeyType)keyType {
self = [super init];
if (self) {
_secKeyRef = (SecKeyRef)CFRetain(secKeyRef);
_keyType = keyType;
_keySize = SecKeyGetBlockSize(secKeyRef) * 8;
// 转换为DER格式数据
CFErrorRef error = NULL;
CFDataRef keyDataRef = SecKeyCopyExternalRepresentation(secKeyRef, &error);
if (error) {
CFRelease(error);
_keyData = nil;
} else {
_keyData = (__bridge_transfer NSData *)keyDataRef;
}
}
return self;
}
- (instancetype)initWithData:(NSData *)keyData keyType:(RSAKeyType)keyType {
self = [super init];
if (self) {
_keyData = keyData;
_keyType = keyType;
// 创建SecKeyRef
NSMutableDictionary *attributes = [NSMutableDictionary dictionary];
attributes[(__bridge id)kSecAttrKeyType] = (__bridge id)kSecAttrKeyTypeRSA;
attributes[(__bridge id)kSecAttrKeyClass] = (keyType == RSAKeyTypePublic) ?
(__bridge id)kSecAttrKeyClassPublic : (__bridge id)kSecAttrKeyClassPrivate;
attributes[(__bridge id)kSecAttrKeySizeInBits] = @(keyData.length * 8);
CFErrorRef error = NULL;
_secKeyRef = SecKeyCreateWithData((__bridge CFDataRef)keyData,
(__bridge CFDictionaryRef)attributes,
&error);
if (error) {
NSLog(@"Failed to create SecKeyRef: %@", (__bridge NSError *)error);
CFRelease(error);
return nil;
}
_keySize = SecKeyGetBlockSize(_secKeyRef) * 8;
}
return self;
}
- (void)dealloc {
if (_secKeyRef) {
CFRelease(_secKeyRef);
}
}
@end
@implementation CryptoManager
#pragma mark - AES 加解密实现
+ (NSData *)AESEncryptData:(NSData *)data
withKey:(NSData *)key
iv:(NSData *)iv
mode:(AESCipherMode)mode
padding:(AESPaddingOption)padding {
// 严格验证密钥长度
if (key.length != kCCKeySizeAES128 &&
key.length != kCCKeySizeAES192 &&
key.length != kCCKeySizeAES256) {
NSLog(@"❌ Invalid AES key length: %lu. Must be 16, 24 or 32 bytes", (unsigned long)key.length);
return nil;
}
// 验证需要 IV 的模式
if (mode != AESCipherModeECB) {
if (!iv || iv.length != kCCBlockSizeAES128) {
NSLog(@"❌ Invalid IV for mode %lu. Must be %d bytes", (unsigned long)mode, kCCBlockSizeAES128);
return nil;
}
}
// 验证无填充模式的数据对齐
if (padding == AESPaddingNone && data.length % kCCBlockSizeAES128 != 0) {
NSLog(@"❌ Data length (%lu) must be multiple of block size (%d) for no padding",
(unsigned long)data.length, kCCBlockSizeAES128);
return nil;
}
// 设置加密参数
CCOperation operation = kCCEncrypt;
CCAlgorithm algorithm = kCCAlgorithmAES;
CCOptions options = 0;
// 设置模式选项
switch (mode) {
case AESCipherModeECB: options |= kCCOptionECBMode; break;
case AESCipherModeCBC: break; // 默认是 CBC
case AESCipherModeCFB: options |= kCCModeCFB; break;
case AESCipherModeOFB: options |= kCCModeOFB; break;
case AESCipherModeCTR: options |= kCCModeCTR; break;
}
// 设置填充选项
if (padding == AESPaddingPKCS7) {
options |= kCCOptionPKCS7Padding;
}
// 无填充不需要额外选项
// 计算缓冲区大小(考虑填充)
size_t bufferSize = data.length + kCCBlockSizeAES128;
void *buffer = malloc(bufferSize);
if (!buffer) return nil;
size_t processedBytes = 0;
CCCryptorStatus cryptStatus = CCCrypt(operation,
algorithm,
options,
key.bytes,
key.length,
(mode == AESCipherModeECB) ? NULL : iv.bytes, // ECB 忽略 IV
data.bytes,
data.length,
buffer,
bufferSize,
&processedBytes);
if (cryptStatus != kCCSuccess) {
free(buffer);
NSLog(@"🔒 AES encryption failed with status: %d (%@)", cryptStatus, [self descriptionForCryptStatus:cryptStatus]);
return nil;
}
return [NSData dataWithBytesNoCopy:buffer length:processedBytes];
}
+ (NSString *)descriptionForCryptStatus:(CCCryptorStatus)status {
switch (status) {
case kCCSuccess: return @"Success";
case kCCParamError: return @"Invalid parameter";
case kCCBufferTooSmall: return @"Buffer too small";
case kCCMemoryFailure: return @"Memory allocation failure";
case kCCAlignmentError: return @"Input data alignment error";
case kCCDecodeError: return @"Decoding error (typically format error)";
case kCCUnimplemented: return @"Function not implemented";
case kCCOverflow: return @"Overflow";
case kCCRNGFailure: return @"Random number generator failure";
case kCCUnspecifiedError: return @"Unspecified error";
case kCCCallSequenceError: return @"Invalid call sequence";
case kCCKeySizeError: return @"Invalid key size";
default: return [NSString stringWithFormat:@"Unknown error (%d)", status];
}
}
+ (NSData *)AESDecryptData:(NSData *)encryptedData
withKey:(NSData *)key
iv:(NSData *)iv
mode:(AESCipherMode)mode
padding:(AESPaddingOption)padding {
// 验证密钥长度
if (key.length != kCCKeySizeAES128 &&
key.length != kCCKeySizeAES192 &&
key.length != kCCKeySizeAES256) {
NSLog(@"Invalid AES key length: %lu. Must be 16, 24 or 32 bytes", (unsigned long)key.length);
return nil;
}
// 验证需要 IV 的模式
if (mode != AESCipherModeECB && (!iv || iv.length != kCCBlockSizeAES128)) {
NSLog(@"Invalid IV for mode %lu. Must be %d bytes", (unsigned long)mode, kCCBlockSizeAES128);
return nil;
}
// 设置加密参数
CCOperation operation = kCCDecrypt;
CCAlgorithm algorithm = kCCAlgorithmAES;
// 声明并初始化 options 变量 - 修复点
CCOptions options = 0;
// 设置模式选项
switch (mode) {
case AESCipherModeECB: options |= kCCOptionECBMode; break;
case AESCipherModeCFB: options |= kCCModeCFB; break;
case AESCipherModeOFB: options |= kCCModeOFB; break;
case AESCipherModeCTR: options |= kCCModeCTR; break;
case AESCipherModeCBC: // 默认
default: break;
}
// 设置填充选项
if (padding == AESPaddingPKCS7) {
options |= kCCOptionPKCS7Padding;
}
// 计算缓冲区大小
size_t bufferSize = encryptedData.length + kCCBlockSizeAES128;
void *buffer = malloc(bufferSize);
if (!buffer) return nil;
size_t processedBytes = 0;
const void *ivBytes = (mode == AESCipherModeECB) ? NULL : iv.bytes;
CCCryptorStatus cryptStatus = CCCrypt(operation,
algorithm,
options,
key.bytes,
key.length,
ivBytes,
encryptedData.bytes,
encryptedData.length,
buffer,
bufferSize,
&processedBytes);
if (cryptStatus != kCCSuccess) {
free(buffer);
NSLog(@"AES decryption failed with status: %d (%@)",
cryptStatus, [self descriptionForCryptStatus:cryptStatus]);
return nil;
}
NSData *decryptedData = [NSData dataWithBytesNoCopy:buffer length:processedBytes];
// 如果是PKCS7填充,则移除填充
if (padding == AESPaddingPKCS7 && decryptedData.length > 0) {
// 获取最后一个字节的值(填充长度)
uint8_t paddingLength = 0;
[decryptedData getBytes:&paddingLength
range:NSMakeRange(decryptedData.length - 1, 1)];
// 验证填充是否有效 (1-16 字节)
if (paddingLength > 0 && paddingLength <= kCCBlockSizeAES128) {
// 检查最后 paddingLength 个字节是否都是 paddingLength
BOOL isValidPadding = YES;
const uint8_t *bytes = decryptedData.bytes;
NSUInteger dataLength = decryptedData.length;
for (NSUInteger i = 1; i <= paddingLength; i++) {
if (bytes[dataLength - i] != paddingLength) {
isValidPadding = NO;
break;
}
}
if (isValidPadding) {
// 移除填充
decryptedData = [decryptedData subdataWithRange:
NSMakeRange(0, dataLength - paddingLength)];
} else {
NSLog(@"⚠️ Invalid PKCS7 padding detected. Data may be corrupted.");
}
}
}
return decryptedData;
}
#pragma mark - RSA 密钥处理
+ (RSAKey *)createRSAKeyFromPEM:(NSString *)pemString keyType:(RSAKeyType)keyType {
// 清理PEM格式
NSString *cleanedPEM = [[pemString componentsSeparatedByCharactersInSet:
[NSCharacterSet whitespaceAndNewlineCharacterSet]]
componentsJoinedByString:@""];
// 移除PEM头尾标记
NSString *header = @"";
NSString *footer = @"";
if (keyType == RSAKeyTypePublic) {
header = @"-----BEGINPUBLICKEY-----";
footer = @"-----ENDPUBLICKEY-----";
} else {
header = @"-----BEGINPRIVATEKEY-----";
footer = @"-----ENDPRIVATEKEY-----";
}
cleanedPEM = [cleanedPEM stringByReplacingOccurrencesOfString:header withString:@""];
cleanedPEM = [cleanedPEM stringByReplacingOccurrencesOfString:footer withString:@""];
// Base64解码
NSData *keyData = [self dataFromBase64EncodedString:cleanedPEM];
if (!keyData) {
NSLog(@"Failed to decode base64 key");
return nil;
}
return [self createRSAKeyFromDER:keyData keyType:keyType];
}
+ (RSAKey *)createRSAKeyFromDER:(NSData *)derData keyType:(RSAKeyType)keyType {
NSDictionary *attributes = @{
(__bridge id)kSecAttrKeyType: (__bridge id)kSecAttrKeyTypeRSA,
(__bridge id)kSecAttrKeyClass: (keyType == RSAKeyTypePublic) ?
(__bridge id)kSecAttrKeyClassPublic : (__bridge id)kSecAttrKeyClassPrivate,
(__bridge id)kSecAttrKeySizeInBits: @(derData.length * 8)
};
CFErrorRef error = NULL;
SecKeyRef secKey = SecKeyCreateWithData((__bridge CFDataRef)derData,
(__bridge CFDictionaryRef)attributes,
&error);
if (error) {
NSError *err = (__bridge NSError *)error;
NSLog(@"Failed to create SecKeyRef: %@", err.localizedDescription);
CFRelease(error);
return nil;
}
return [[RSAKey alloc] initWithSecKeyRef:secKey keyType:keyType];
}
#pragma mark - RSA 加密/解密
+ (NSData *)RSAEncryptData:(NSData *)data
withRSAKey:(RSAKey *)rsaKey
padding:(RSAEncryptionPadding)padding {
// 验证参数
if (!data || !rsaKey || rsaKey.keyType != RSAKeyTypePublic) {
NSLog(@"Invalid parameters for RSA encryption");
return nil;
}
// 计算最大加密长度
size_t keyBlockSize = SecKeyGetBlockSize(rsaKey.secKeyRef);
size_t maxPlainSize = 0;
switch (padding) {
case RSAEncryptionPaddingPKCS1:
maxPlainSize = keyBlockSize - 11; // PKCS1 padding overhead
break;
case RSAEncryptionPaddingOAEP:
maxPlainSize = keyBlockSize - 42; // OAEP padding overhead
break;
}
if (data.length > maxPlainSize) {
NSLog(@"Data too long for RSA encryption with selected padding");
return nil;
}
// 设置算法
SecKeyAlgorithm algorithm;
if (padding == RSAEncryptionPaddingPKCS1) {
algorithm = kSecKeyAlgorithmRSAEncryptionPKCS1;
} else {
algorithm = kSecKeyAlgorithmRSAEncryptionOAEPSHA256;
}
// 验证算法是否支持
if (!SecKeyIsAlgorithmSupported(rsaKey.secKeyRef, kSecKeyOperationTypeEncrypt, algorithm)) {
NSLog(@"Unsupported algorithm for RSA encryption");
return nil;
}
// 执行加密
CFErrorRef error = NULL;
CFDataRef encryptedData = SecKeyCreateEncryptedData(rsaKey.secKeyRef,
algorithm,
(__bridge CFDataRef)data,
&error);
if (error) {
NSError *err = (__bridge NSError *)error;
NSLog(@"RSA encryption failed: %@", err.localizedDescription);
CFRelease(error);
return nil;
}
return (__bridge_transfer NSData *)encryptedData;
}
+ (NSData *)RSADecryptData:(NSData *)encryptedData
withRSAKey:(RSAKey *)rsaKey
padding:(RSAEncryptionPadding)padding {
// 验证参数
if (!encryptedData || !rsaKey || rsaKey.keyType != RSAKeyTypePrivate) {
NSLog(@"Invalid parameters for RSA decryption");
return nil;
}
// 设置算法
SecKeyAlgorithm algorithm;
if (padding == RSAEncryptionPaddingPKCS1) {
algorithm = kSecKeyAlgorithmRSAEncryptionPKCS1;
} else {
algorithm = kSecKeyAlgorithmRSAEncryptionOAEPSHA256;
}
// 验证算法是否支持
if (!SecKeyIsAlgorithmSupported(rsaKey.secKeyRef, kSecKeyOperationTypeDecrypt, algorithm)) {
NSLog(@"Unsupported algorithm for RSA decryption");
return nil;
}
// 执行解密
CFErrorRef error = NULL;
CFDataRef decryptedData = SecKeyCreateDecryptedData(rsaKey.secKeyRef,
algorithm,
(__bridge CFDataRef)encryptedData,
&error);
if (error) {
NSError *err = (__bridge NSError *)error;
NSLog(@"RSA decryption failed: %@", err.localizedDescription);
CFRelease(error);
return nil;
}
return (__bridge_transfer NSData *)decryptedData;
}
#pragma mark - RSA 签名/验证
+ (NSData *)RSASignData:(NSData *)data
withRSAKey:(RSAKey *)rsaKey
digestType:(RSASignatureDigestType)digestType {
// 验证参数
if (!data || !rsaKey || rsaKey.keyType != RSAKeyTypePrivate) {
NSLog(@"Invalid parameters for RSA signature");
return nil;
}
// 设置算法
SecKeyAlgorithm algorithm;
switch (digestType) {
case RSASignatureDigestTypeSHA1:
algorithm = kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA1;
break;
case RSASignatureDigestTypeSHA224:
algorithm = kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA224;
break;
case RSASignatureDigestTypeSHA256:
algorithm = kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA256;
break;
case RSASignatureDigestTypeSHA384:
algorithm = kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA384;
break;
case RSASignatureDigestTypeSHA512:
algorithm = kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA512;
break;
default:
NSLog(@"Unsupported digest type for RSA signature");
return nil;
}
// 验证算法是否支持
if (!SecKeyIsAlgorithmSupported(rsaKey.secKeyRef, kSecKeyOperationTypeSign, algorithm)) {
NSLog(@"Unsupported algorithm for RSA signature");
return nil;
}
// 执行签名
CFErrorRef error = NULL;
CFDataRef signature = SecKeyCreateSignature(rsaKey.secKeyRef,
algorithm,
(__bridge CFDataRef)data,
&error);
if (error) {
NSError *err = (__bridge NSError *)error;
NSLog(@"RSA signature failed: %@", err.localizedDescription);
CFRelease(error);
return nil;
}
return (__bridge_transfer NSData *)signature;
}
+ (BOOL)RSAVerifySignature:(NSData *)data
signature:(NSData *)signatureData
withRSAKey:(RSAKey *)rsaKey
digestType:(RSASignatureDigestType)digestType {
// 验证参数
if (!data || !signatureData || !rsaKey || rsaKey.keyType != RSAKeyTypePublic) {
NSLog(@"Invalid parameters for RSA verification");
return NO;
}
// 设置算法
SecKeyAlgorithm algorithm;
switch (digestType) {
case RSASignatureDigestTypeSHA1:
algorithm = kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA1;
break;
case RSASignatureDigestTypeSHA224:
algorithm = kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA224;
break;
case RSASignatureDigestTypeSHA256:
algorithm = kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA256;
break;
case RSASignatureDigestTypeSHA384:
algorithm = kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA384;
break;
case RSASignatureDigestTypeSHA512:
algorithm = kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA512;
break;
default:
NSLog(@"Unsupported digest type for RSA verification");
return NO;
}
// 验证算法是否支持
if (!SecKeyIsAlgorithmSupported(rsaKey.secKeyRef, kSecKeyOperationTypeVerify, algorithm)) {
NSLog(@"Unsupported algorithm for RSA verification");
return NO;
}
// 执行验证
CFErrorRef error = NULL;
BOOL result = SecKeyVerifySignature(rsaKey.secKeyRef,
algorithm,
(__bridge CFDataRef)data,
(__bridge CFDataRef)signatureData,
&error);
if (error) {
NSError *err = (__bridge NSError *)error;
NSLog(@"RSA verification failed: %@", err.localizedDescription);
CFRelease(error);
return NO;
}
return result;
}
#pragma mark - 实用工具方法
+ (NSData *)randomDataOfLength:(size_t)length {
NSMutableData *data = [NSMutableData dataWithLength:length];
int result = SecRandomCopyBytes(kSecRandomDefault, length, data.mutableBytes);
if (result != errSecSuccess) {
NSLog(@"Failed to generate random data: %d", result);
return nil;
}
return [data copy];
}
+ (NSString *)hexStringFromData:(NSData *)data {
const unsigned char *bytes = (const unsigned char *)data.bytes;
NSMutableString *hexString = [NSMutableString stringWithCapacity:data.length * 2];
for (NSUInteger i = 0; i < data.length; i++) {
[hexString appendFormat:@"%02x", bytes[i]];
}
return [hexString copy];
}
+ (NSData *)dataFromHexString:(NSString *)hexString {
NSMutableData *data = [NSMutableData new];
for (NSUInteger i = 0; i < hexString.length; i += 2) {
NSString *byteString = [hexString substringWithRange:NSMakeRange(i, 2)];
NSScanner *scanner = [NSScanner scannerWithString:byteString];
unsigned int byteValue;
if (![scanner scanHexInt:&byteValue]) return nil;
[data appendBytes:&byteValue length:1];
}
return [data copy];
}
+ (NSData *)dataFromBase64EncodedString:(NSString *)base64String {
return [[NSData alloc] initWithBase64EncodedString:base64String options:0];
}
+ (NSString *)base64EncodedStringFromData:(NSData *)data {
return [data base64EncodedStringWithOptions:0];
}
@end
示例如下:
// 1. 初始化密钥
NSString *aesKeyStr = @"fgBAGorQi/BlZ9GJFQvNZA==";
// 2. 创建RSA秘钥
RSAKey *privateKey = [CryptoManager createRSAKeyFromPEM:@"替换真实privateKey" keyType:RSAKeyTypePublic];
RSAKey *publicKey = [CryptoManager createRSAKeyFromPEM:@"替换真实publicKey" keyType:RSAKeyTypePublic];
// 3. 准备原始数据
NSString *originalText = @"123456789";
NSData *originalData = [originalText dataUsingEncoding:NSUTF8StringEncoding];
// 4. AES加密 (使用CBC模式)
NSData *aesKey = [CryptoManager dataFromBase64EncodedString:aesKeyStr];
NSData *iv = [CryptoManager randomDataOfLength:kCCBlockSizeAES128]; // 随机生成IV
NSData *encryptedData = [CryptoManager AESEncryptData:originalData
withKey:aesKey
iv:iv
mode:AESCipherModeCBC
padding:AESPaddingPKCS7];
NSString *encryptedText = [CryptoManager base64EncodedStringFromData:encryptedData];
// 5. RSA签名 (模拟服务端行为)
NSData *signature = [CryptoManager RSASignData:encryptedData
withRSAKey:privateKey
digestType:RSASignatureDigestTypeSHA256];
NSString *signatureText = [CryptoManager base64EncodedStringFromData:signature];
// 6. 客户端验证
// 6.1 验证签名
BOOL isSignatureValid = [CryptoManager RSAVerifySignature:encryptedData
signature:signature
withRSAKey:publicKey
digestType:RSASignatureDigestTypeSHA256];
NSLog(@"签名验证: %@", isSignatureValid ? @"成功" : @"失败");
// 6.2 AES解密
NSData *decryptedData = [CryptoManager AESDecryptData:encryptedData
withKey:aesKey
iv:iv
mode:AESCipherModeCBC
padding:AESPaddingPKCS7];
NSString *decryptedText = [[NSString alloc] initWithData:decryptedData encoding:NSUTF8StringEncoding];
NSLog(@"AES解密结果: %@", decryptedText);
// 7. 使用不同模式解密 (例如ECB模式)
NSData *ecbEncryptedData = [CryptoManager AESEncryptData:originalData
withKey:aesKey
iv:nil
mode:AESCipherModeECB
padding:AESPaddingPKCS7];
NSData *ecbDecryptedData = [CryptoManager AESDecryptData:ecbEncryptedData
withKey:aesKey
iv:nil
mode:AESCipherModeECB
padding:AESPaddingPKCS7];
NSString *ecbDecryptedText = [[NSString alloc] initWithData:ecbDecryptedData encoding:NSUTF8StringEncoding];
NSLog(@"ECB模式解密结果: %@", ecbDecryptedText);