加解密工具类

87 阅读9分钟

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);