You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

iOS平台如何确保安全框架不被越狱用户替换?

iOS平台防止安全框架被替换的最佳方案

核心思路:代码签名验证 + 运行时完整性校验

iOS的代码签名机制是基础防护,要确保安全框架被篡改后无法通过系统校验,同时在APP运行时主动完成框架签名与完整性的双重验证——这是应对越狱环境篡改的关键。

一、利用苹果代码签名的基础保障

你的安全框架必须和主APP使用同一开发者账号/签名身份打包编译。正常情况下,iOS系统会拒绝加载未签名、签名非法或与主APP签名身份不匹配的动态框架;但越狱环境下存在工具可绕过系统校验,因此必须补充主动校验逻辑。

二、运行时校验框架签名的实现

在APP启动阶段(建议在框架加载前或初始化时),获取当前框架的签名哈希,与预存的合法签名哈希比对,不一致则触发保护逻辑(终止APP/禁用安全功能)。

1. 获取框架签名哈希的示例代码

#import <Foundation/Foundation.h>
#import <Security/Security.h>

NSString *getFrameworkSignatureHash(NSString *frameworkPath) {
    NSURL *frameworkURL = [NSURL fileURLWithPath:frameworkPath];
    SecStaticCodeRef staticCode = NULL;
    OSStatus status = SecStaticCodeCreateWithPath((CFURLRef)frameworkURL, kSecCSDefaultFlags, &staticCode);
    if (status != errSecSuccess) {
        CFRelease(staticCode);
        return nil;
    }
    
    SecCodeRef dynamicCode = NULL;
    status = SecCodeCopyGuestWithAttributes(staticCode, kSecCSDefaultFlags, NULL, &dynamicCode);
    if (status != errSecSuccess) {
        CFRelease(staticCode);
        CFRelease(dynamicCode);
        return nil;
    }
    
    CFDictionaryRef info = NULL;
    status = SecCodeCopySigningInformation(dynamicCode, kSecCSDefaultFlags, &info);
    if (status != errSecSuccess) {
        CFRelease(staticCode);
        CFRelease(dynamicCode);
        CFRelease(info);
        return nil;
    }
    
    // 获取SHA-256格式的签名哈希
    NSData *signatureHash = (__bridge NSData *)CFDictionaryGetValue(info, kSecCodeInfoSignatureHash);
    NSString *hashString = [signatureHash base64EncodedStringWithOptions:0];
    
    CFRelease(staticCode);
    CFRelease(dynamicCode);
    CFRelease(info);
    
    return hashString;
}

2. 校验逻辑实现

  • 预计算合法框架的签名哈希:将编译后的框架通过上述代码或命令行工具生成哈希值,通过编译时嵌入二进制常量、加密存储到Keychain等方式保存(需做混淆处理,避免明文泄露)。
  • 启动校验:在application:didFinishLaunchingWithOptions:中调用上述方法,获取当前框架的签名哈希并与预存值比对,不一致则立即执行保护逻辑。

三、越狱环境的额外防护

  1. 越狱检测前置:在签名校验前先检测设备是否越狱,触发检测后直接拒绝加载安全框架:
BOOL isJailbroken() {
    // 检查越狱标志性文件
    NSArray *jailbreakFiles = @[
        @"/Applications/Cydia.app",
        @"/private/var/stash",
        @"/private/var/lib/apt/"
    ];
    for (NSString *path in jailbreakFiles) {
        if ([[NSFileManager defaultManager] fileExistsAtPath:path]) {
            return YES;
        }
    }
    // 检查是否能加载越狱常用动态库
    void *handle = dlopen("/usr/lib/libsubstrate.dylib", RTLD_NOW);
    if (handle != NULL) {
        dlclose(handle);
        return YES;
    }
    return NO;
}
  1. 启用Hardened Runtime:在Xcode的Build Settings中开启Hardened Runtime,勾选Disable Debugging和Enable Library Validation——这会阻止第三方调试器附加,同时禁止加载未签名的动态库。
  2. 代码混淆:对签名校验、越狱检测的核心代码做混淆处理,防止攻击者逆向分析并绕过校验逻辑。

四、入门实施步骤

  1. 框架签名配置:在框架Target的Signing & Capabilities中选择与主APP一致的Team和Provisioning Profile,编译后框架会自动完成合法签名。
  2. 生成合法签名哈希:编译框架后,可通过命令行工具获取哈希:
# 提取签名信息并获取哈希
security cms -D -i /path/to/YourFramework.framework/_CodeSignature/CodeResources | grep -A 5 "Hash"
  1. 集成校验逻辑:将签名校验与越狱检测代码集成到主APP启动流程,确保框架加载前完成验证。
  2. 测试验证:
    • 正常环境:APP加载框架,校验通过后正常运行。
    • 篡改框架:替换为未签名/非法签名的框架,APP检测到哈希不一致并触发保护。
    • 越狱环境:APP检测到越狱,拒绝加载安全框架。

注意事项

  • 预存的签名哈希不可明文存储,需做加密或混淆处理。
  • 校验逻辑必须放在主APP中,不可放在被保护的框架内(否则框架被替换后校验逻辑也会失效)。
  • 所有实现需符合苹果App Store审核规则,上述代码使用的均为公开API,Hardened Runtime为苹果官方支持的安全机制。

内容的提问来源于stack exchange,提问作者Tolgay Toklar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 17:42:46