本模块(iOS轻舟网络验证)用于在 App 启动阶段对授权码进行本地 + 远程校验,并在成功后进入业务功能。支持防篡改、签名验真、时间窗校验(默认 300s),并提供可定制的成功回调接入位。
组件 | 用途 |
---|---|
commsec_guard.h | 防篡改/完整性检测 |
commsec.h | 封装加解密、HMAC(CommSec_EncryptPayload / Decrypt / HmacSha256Hex) |
libcurl(或 NSURLSession) | 网络请求 |
cJSON | JSON 解析与构造 |
CommonCrypto | SHA-256/HMAC |
UIKit | Alert 与 UI 表达 |
NSURLSession
。密钥放在混淆模块或通过后端下发;不要明文保存在仓库与 NSUserDefaults。在 sub_19745_ex
成功分支中,标有 // TODO: 这里进入你的功能 的位置即为接入点。下面提供四种接入方式。
void EnterMainFeature(const char *expiry){
NSString *exp = expiry ? [NSString stringWithUTF8String:expiry] : @"";
NSLog(@"授权通过,到期:%@", exp);
}
EnterMainFeature(time1);
@protocol ActivationHandler <NSObject>
- (void)activationDidSucceedWithExpiry:(NSString*)expiry;
@end
@interface AppDelegate () <ActivationHandler> @end
@implementation AppDelegate
- (void)activationDidSucceedWithExpiry:(NSString *)expiry {}
@end
id<ActivationHandler> h = (id<ActivationHandler>)[[UIApplication sharedApplication] delegate];
if([h respondsToSelector:@selector(activationDidSucceedWithExpiry:)]){
[h activationDidSucceedWithExpiry:[NSString stringWithUTF8String:time1]];
}
[[NSNotificationCenter defaultCenter] postNotificationName:@"ActivationDidSucceedNotification" object:nil userInfo:@{@"expiry":[NSString stringWithUTF8String:time1]}];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onActivation:) name:@"ActivationDidSucceedNotification" object:nil];
- (void)onActivation:(NSNotification*)n{
NSString *exp = n.userInfo[@"expiry"];
}
typedef void (^ActivationCallback)(NSString *expiry);
static ActivationCallback g_activation_cb = nil;
void SetActivationCallback(ActivationCallback cb){ g_activation_cb = [cb copy]; }
if(g_activation_cb) g_activation_cb([NSString stringWithUTF8String:time1]);
SetActivationCallback(^(NSString *expiry){});
建议:构建阶段完成混淆并写入源码或资源,运行时解混淆后立即使用并清理。
#include <stdlib.h>
#include <string.h>
static const unsigned char OBFUSCATED_KEYS[] = {0x1f,0x2b,0x17,0x3a};
static const unsigned char XOR_KEY = 0x5A;
char *xor_deobfuscate(const unsigned char *data,size_t len,unsigned char key){
char *out=(char*)malloc(len+1);
if(!out) return NULL;
for(size_t i=0;i<len;++i) out[i]=(char)(data[i]^key^(unsigned char)(i&0xFF));
out[len]='\0';
return out;
}
#import <Foundation/Foundation.h>
static NSString * const kEncodedKey = @"R0hJS0JBS0J...";
NSString *RecoverKeysFromEncoded(void){
NSData *b=[[NSData alloc]initWithBase64EncodedString:kEncodedKey options:0];
if(!b) return nil;
size_t len=b.length;
const unsigned char *bytes=(const unsigned char *)b.bytes;
NSMutableData *out=[NSMutableData dataWithLength:len];
unsigned char xorKey=0x5A;
for(size_t i=0;i<len;++i){
unsigned char v=bytes[i]^xorKey^(unsigned char)(i&0xFF);
((unsigned char*)out.mutableBytes)[i]=v;
}
NSString *keys=[[NSString alloc]initWithData:out encoding:NSUTF8StringEncoding];
memset(out.mutableBytes,0,len);
return keys;
}
字段 | 说明 |
---|---|
code | 用户输入的授权码 |
uuid | 设备指纹(CommSec_GetDeviceId) |
appid/appv | 软件代号/版本 |
ts | 秒级时间戳 |
sig | HMAC_SHA256(KEYS,"code|uuid|appid|appv|ts") |
auto | 是否静默验证("1":自动) |
date=="99999"
且 state=="success"
方可放行。www.m/www.h
与 commsec
库,连接 libcurl
或替换为 NSURLSession
。-ObjC
;保持构造函数可执行。CommSecGuard_AbortIfTampered()
。为什么会提示“服务器时间无效”? 端到端时间差超过 300s;请提示用户校时或在失败时引导重试。