高级安全实践:CocoaPods-Keys —— 管理你的iOS应用密钥
项目地址:https://gitcode.com/orta/cocoapods-keys
在开发过程中,保持生产环境的钥匙远离开发者是良好的安全习惯。CocoaPods-Keys提供了一种解决方案,它允许你在开发者的关键链中存储配置设置,而不是在应用源代码中。这是一个插件,在安装后将在每次执行pod install
或pod update
时自动运行。
替代方案
如果你对这个概念感兴趣,但想要一个全新的思考,可以查看Arkana项目,它是CocoaPods-Keys的一个现代替代品。
系统要求
CocoaPods-Keys需要CocoaPods版本0.36+。
安装
在终端中输入以下命令来安装:
$ gem install cocoapods-keys
工作原理
键值被存储在~/.cocoapods/keys/
目录下,而实际的键值则保存在OS X的安全关键链中。当执行pod install
或pod update
时,会自动生成一个经过混淆处理的Objective-C类,这样即使有人试图通过dumpdecrypted获取解密后的二进制文件内容,也难以提取出这些键值。在运行时,这些键值会被解谜以供你的应用程序使用。
自动生成的Objective-C类存放在Pods/CocoaPodsKeys
目录,所以如果你将Pods
目录添加到源控制管理中,别忘了在.gitignore
文件中忽略Pods/CocoaPodsKeys
。CocoaPods-Keys支持Swift和Objective-C项目的整合。
使用方法
利用CocoaPods的新Plugin API,我们可以自动化处理许多繁琐的步骤。你只需要在你的Podfile
中定义所需的关键值(见下方示例),CocoaPods-Keys就会检测并提示尚未设置的键值,确保每个人都能有相同的配置。
plugin 'cocoapods-keys', {
:project => "你的项目名",
:keys => [
"你的第一个密钥",
"你的第二个密钥",
...
]}
请注意不要在键名中使用破折号,详情见问题#197。
然后运行pod install
,系统将会提示设置未设置的键值。
另类使用方式
如果希望为每个项目单独保存键值,可以通过运行命令来设置:
$ bundle exec pod keys set 键名称 值
要列出所有已知的键值,只需运行:
$ bundle exec pod keys
例如:
$ cd 我的应用
$ bundle exec pod keys set "网络API令牌" "ah2zmiraGqbyud9gknTnfwedxlwxchciefoh"
将网络API令牌保存到了我的应用。
$ bundle exec pod keys set "统计令牌" "6tykgvcn7sbbsbfpwfsucclzdosbtexw7"
将统计令牌保存到了我的应用。
$ bundle exec pod keys
我的应用的键值
├ 网络API令牌 - ah2zmiraGqbyud9gknTnfwedxlwxchciefoh
└ 统计令牌 - 6tykgvcn7sbbsbfpwfsucclzdosbtexw7
...
下次执行pod install
或pod update
时,键值会添加一个新的Keys
到你的Pods项目中,支持静态库和框架。请注意在Podfile
中包含plugin 'cocoapods-keys'
,才能使Keys注册并开始工作。这会为你的Cocoa代码提供访问键值的API。例如,应用程序代码可能如下所示:
#import "ORAppDelegate.h"
#import <Keys/你的项目名Keys.h>
#import <ARAnalytics/ARAnalytics.h>
@implementation ORAppDelegate
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
你的项目名Keys *keys = [[你的项目名Keys alloc] init];
[ARAnalytics setupWithAnalytics:@{
ARGoogleAnalyticsID : keys.统计令牌;
}];
}
@end
还有文档可以帮助你在Swift项目中使用CocoaPods-Keys。
其他命令
CocoaPods-Keys提供了其他三个命令:
-
bundle exec pod keys get [键] [可选项目]
输出指定键的值,用于脚本编程。 -
bundle exec pod keys rm [键] [可选项目]
删除指定项目中的键。如果使用通配符,将会移除与模式匹配的所有键。例如:
bundle exec pod keys rm "G*og*"
将移除所有以"G"开头,中间含有"og",末尾任意的键。要删除所有键,可以运行bundle exec pod keys rm "*" 或
bundle exec pod keys rm --all`。 -
bundle exec pod keys generate [可选项目]
生成混淆的Objective-C键值类(主要用于内部使用)。
持续集成
不建议在CI环境中操作关键链,因此在找不到环境变量的情况下,键值会查找相同字符串。此外,可以在项目目录创建.env
文件。
维护状态
CocoaPods-Keys对于Artsy公司来说已经是"完成"状态的软件。它已经满足了我们多年的需求。所以我们不会接受新功能请求(除非我们自己需要)。但是我们会保证它的正常工作。
安全性
密钥安全管理是困难的。目前,即使是最大的应用也会发生密钥泄露的情况。这个问题被Twitter安全团队的John Adams在Quora上进行了总结:
把它放在"是否应该在软件中存储密钥"的情境下来考虑更为合适。很多公司都会这样做。但这从来不是一个好主意。
当开发者这么做时,其他开发者可以用调试器和字符串搜索命令从运行中的应用中提取这些密钥。有许多关于如何做到这一点的演讲,但这些留给读者自己去寻找。
许多人认为混淆这些密钥在代码中会有帮助。但通常情况下并没有,因为你只需运行一个调试器就可以找到完全有效的密钥。
所以总的来说,理想的密钥存储方法就是不要存储密钥。然而在现实中,大多数应用都嵌入了密钥,CocoaPods-Keys做到了这一点,并且对密钥进行了一些基本的混淆处理。一个动机强烈的App破解者可能会在几分钟内提取出来。
致谢
此项目由@segiddins,@ashfurrow 和 @marcelofabri提供大量帮助。