这个工具由两个组件组成
为了标记一个常量字符串为“混淆”,开发者只需在字符串定义旁边指定编译器指令 __obfuscated
,如下所示
__obfuscated NSString * const myPrivateKey = @"234ba9c824cd578ef924a5f0";
然后运行由 gem 提供的命令行工具
$ objc-obfuscator obfuscate myEncryptionKey my_file.m
此时,源文件中的明文密钥将被加密副本替换
NSString * const myPrivateKey = @"ZQdnkwPtba2asdCu12nHZQ==-Jjh28cbD1YsyAd2X+jLZLg==-MTM5MDgyMjIzNg==";
由于字符串现在是加密格式存储的,每次使用时都必须进行解密。Objective C 库提供了一个对 NSString 的扩展,允许在运行时轻松解码。
NSString *unencryptedKey = [myPrivateKey unobfuscatedString];
此时唯一的额外步骤是包含和配置 Objective C 库,并使用正确的密钥,以便 unobfuscatedString
方法知道如何解密字符串。在应用程序代理中,请确保添加以下内容
[[FWTObfuscator defaultObfuscator] setEncryptionKey:@"myEncryptionKey"];
有些人可能会注意到我们最初提出的问题还没有解决:黑客可能查找加密密钥,并使用该密钥解密加密字符串。遗憾的是,由于我们需要将其嵌入最终的二进制文件中(如果我们不想依赖外部服务器连接并处理所有相关的网络问题),因此无法完全保证这个密钥的安全。
我们解决这个问题的方法是使用组合的已知字符串,而不直接在代码中指定它们。这里所指的“已知字符串”是指特定的 Cocoa-Touch 字符串,始终可存在于应用程序的二进制文件中。例如,一个不错的选择可以是一个
NSString *myKey = NSString stringWithFormat:@"%@%@",
NSStringFromClass([NSObject class]),
NSStringFromClass([NSString class]);
组合是其弱点,您需要保持秘密的部分,这就是“隐蔽性”的概念所在。
为了使整个过程对开发者透明,必须在编译源文件之前加密字符串,并在编译之后替换为解密的副本。通过这种方式,我们实现了两个重要的结果
为了实现这一点,我们需要向我们的目标添加两个 Shell 执行阶段:一个在编译之前,一个在编译之后。
这个宝石进一步推动了这个问题,如果你在你的项目中使用了 Cocoapods,你可以使用一条命令整合库。
$ objc-obfuscator integrate myEncryptionKey myproject.xcodeproj
该命令可以通过以下选项适应不同的项目结构。
Usage:
objc-obfuscator integrate [ENCRYPTION_KEY] [PROJECT_FILE]
Options:
[--podfile=PODFILE] # Path to the Podfile.
[--target=TARGET] # Xcode project containing the "compile source" build phase.
这将负责以下工作:
正如我们开头所说的,虽然混淆不会提供额外的安全性,但它有助于隐藏敏感信息,使得逆向工程你的代码变得不那么简单。
提供的加密框架通过使用强大的加密函数和一个由公开在所有 iOS 二进制文件中可用的字符串组合成的密钥来实现这一点。
计算开销是可以忽略不计的(并且可以通过实施缓存来进一步提高)同时从开发者的角度看,整合几乎是透明的。
Objc Obfuscator 适用于 MIT 许可。请参阅 LICENSE 文件以获取更多信息。