[译]在 Git 中保护 iOS 项目的敏感信息

news/2025/3/22 1:37:37

原文链接 (自备梯子)

一些可以保护API key等信息的简单方法

几乎所有 iOS 应用都需要使用一些私有值,比如 API key,HMAC secrets 或密码。有一个简单的途径可以把这些私有值包含到你的 app 中,那就是把它们写在代码里或者写在 Info.plist 文件里。但是这么做会产生一个问题,就是这些文件会被包含到 Git 仓库里,任何人都可以看到并获取到源代码,自然也就可以获取到这些敏感信息。

保护源代码

针对上面提及的问题,首先想到的解决方式可能很简单,就是直接保护源代码,这样其他人就没法获取到源码,也就没办法获取到这些敏感信息了。然而不幸的是很多应用是开源的,每个人都需要去获取其源码,所以这种解决方式并不总是奏效的。对于一些顶级的 iOS app,人们还可以去反编译它或者分析应用包的 Contents 来寻找这些敏感信息。

让文件不包含到 Git 仓库中

在允许保持代码开源的前提下,你可以简单地让包含敏感信息的文件被 Git 忽略。任何人需要在项目中使用这些敏感信息,可以简单地创建相关文件。对于一个开源项目来说,这些相关细节,可以在 README 或者 wiki 页面里注明。

如果按照上面所说,那么一个 iOS 应用,每一个开发者都需要创建一个源代码文件或者一个 plist 文件,然后添加到项目中。这样你不得不很小心地在项目设置里去确保相关文件的引用情况,即使当这些相关文件不包含在 Git 中。

xcconfig

我更倾向于把敏感信息保存在 xcconfig 文件中,每一个编译环境( Debug 或 Release )对应一个文件。这些文件可以让你在不同环境使用不同的配置,为开发者简化配置,而且让敏感信息不包含在 Git 仓库里。

1. 创建一些样例文件在项目里

我更喜欢把它们放在 BuildConfig 文件夹里,让它们与项目里的其他文件分离开。开发者只需要简单地复制它们,给它们重命名,然后把一些敏感信息写到里面。这些样例文件可以指定 key 的列表,但是不把值包含进去。每一个编译版本的配置,比如 Debug 和 Release,都需要这么一个文件。

debug.example.xcconfig
API_CLIENT_ID = API_CLIENT_ID_FOR_TEST
API_CLIENT_SECRET = API_CLIENT_SECRET_FOR_TEST
复制代码
release.example.xcconfig
API_CLIENT_ID = API_CLIENT_ID_FOR_PRODUCTION
API_CLIENT_SECRET = API_CLIENT_SECRET_FOR_PRODUCTION
复制代码

你将需要把这些文件添加到 Xcode 项目中。但是你要确定把他们从 Xcode 的文件检查器的 Target Membership 区域中移除。

2. 为每一个编译版本创建真实文件

在这里面把例子的值替换成项目里真实的值

debug.xcconfig
API_CLIENT_ID = 123456789
API_CLIENT_SECRET = abcdefgh
复制代码
release.xcconfig
API_CLIENT_ID = 987654321
API_CLIENT_SECRET = hgfedcba
复制代码

你将要把这些文件添加到项目中,但是它们不需要依附到任何 target。

3. 把这些配置文件添加到 .gitignore 文件中。

4. 在项目设置里选中这些文件。

你需要在 Info->Configurations 中选中这些文件,在 Debug 和 Release 中都去设置它们。

值的使用

任何包含在 xcconfig 文件的值都可以作为项目文件的环境变量来使用,比如 Info.plist,如果需要再代码里使用这些值,你需要在 Info.plist 创建一个属性链接到环境变量,使用这种格式 $(API_CONFIG_KEY)

2018-02-01 更新

把敏感信息保存在Info.plist 不是最安全的方式。如果你的应该比较注重安全性,那么你可能需要把这些敏感信息放在其他地方。本篇文章的侧重点事把它们排除在 Git 仓库之外。后面我会再更新说明如何在代码中使用这些环境变量,来作为 Info.plist 的代替方案。

2018-02-03 更新

使用 Sourcery,可以生成一个 Swift 结构体,该结构体包含了在 xcconfig 文件里的特定敏感信息。

  1. 把 Sourcery 添加到项目中。

  2. 创建一个 stencil 文件,例如 AppSecrets.stencil,把项目代码里需要访问到的敏感信息都写在这里,作为Swift常量。

struct AppSecrets {static let secretKey="{{ argument.secretKey }}"
}
复制代码
  1. 添加 build phase 来生成 AppSecrets.swift。
Tools/Sourcery/bin/sourcery --sources Sources --templates Templates/AppSecrets.stencil --output Generated --args secretKey=\"$SECRET_KEY\"
复制代码
  • Sourcery 的路径取决于是怎么安装它的,我这例子里是作为一个独立版本工具,将它包含在项目中。
  • 上面那个 sources 参数是必须的,虽然在这种情况下并没有用到,只是在后面输入了一个在项目里的有效路径。
  • 上面 templates 参数是 AppSecrets.stencil 相对于 root 的路径。
  • output 文件夹是 AppSecrets.swift 写入的地方,这个文件夹必须有。你可以在 build phase 添加 mkdir -p Generated 来确保这个文件夹存在。
  • 写这些参数的时候,他们分开的格式应该是这样:arg1=one,arg2=two 。我避免在 SECRET_KEY 内容里添加任何特殊字符。
  1. 把 AppSecrets.swift 加入到 .gitignore 文件中,让它不被添加到 Git 仓库中。
  2. 编译项目,然后把 AppSecrets.swift 加到项目中,这样 AppSecrets.swift 会被编译和链接到项目的 target 中。

注意:如果你的 App key 之类的敏感信息没有要求在不同的编译条件下( debug 和 release) 具有不同的值,你可以跳过 xcconfig 部分。你可以使用另一个方案,那就是把敏感信息写成一个可执行的 shell 脚本,添加到 build phase 中。

总结一下,通过以上这些方法,你可以让你项目中的敏感信息不被加入到 Git 仓库里,与此同时,对于这个项目新的开发者们来说,也比较易于理解上手。


https://dhexx.cn/news/show-2654236.html

相关文章

LeetCode Search in Rotated Sorted Array

题目: Suppose a sorted array is rotated at some pivot unknown to you beforehand. (i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2). You are given a target value to search. If found in the array return its index, otherwise return -1. You may assum…

Use zabbix to Monitor your servers

为什么80%的码农都做不了架构师?>>> 本次主要介绍一款开源免费的分布式监控软件Zabbix的安装使用,底层存储数据用的是Postgres 9.1,以下是步骤: 1.准备 下载zabbix的服务端和客户端文件, 下载地址&#xf…

vue + ueditor 单图片跨域上传

UEditor官网说不提供单图片的跨域,所以只能自己解决。查了网上的很多方案,但是没看到和vue一起用的,不过倒是获得了一些思路。本着不想改太多源代码的基础上尝试着...一不小心就可以用了解决方案:上传单图片的时后端不直接返回JSO…

LeetCode Search in Rotated Sorted Array II

题目: Follow up for "Search in Rotated Sorted Array": What if duplicates are allowed? Would this affect the run-time complexity? How and why? Write a function to determine if a given target is in the array. 题意: 继续上…

管理Oracle实例

前言 正常生产环境下往往是通过应用服务器来与Oracle数据库相连接,大多数使用Oracle的开发语言以Java为主,针对于Java的中间件有很多,我们这里具体来看一下Oracle整体产品线的WLS产品 安装Weblogic 执行上图所示命令,启动WLS安装页…

sklearn学习——特征处理

sklearn学习——特征处理 特征提取(feature extraction): 从文字,图像,声音等其他非结构化数据中提取新信息作为特征。比如说,从淘宝宝贝的名称中提取出产品类别,产品颜色,是否是网红产品等等。 特征创造(feature cre…

环境变量问题

软件出现下面的问题: 解决方法: 直接用export命令:#export PATH$PATH:/usr/local/sbin:/usr/sbin:/sbin

粒子群优化支持向量机代码(PSO-SVM)

粒子群优化支持向量机代码 数据WFs1 import pandas as pd import numpy as np import random from sklearn.svm import SVC import matplotlib.pyplot as plt from sklearn.model_selection import cross_val_predict from sklearn.metrics import confusion_matrix from skl…

LeetCode Bulb Switcher

题目: There are n bulbs that are initially off. You first turn on all the bulbs. Then, you turn off every second bulb. On the third round, you toggle every third bulb (turning on if its off or turning off if its on). For the nth round, you only …

C++操作MySQL,有用的朋友顶下,辛苦的原创啊. - 天下 - C++博客

C操作MySQL,有用的朋友顶下,辛苦的原创啊. - 天下 - C博客C操作MySQL,有用的朋友顶下,辛苦的原创啊.向google大神搜 :mysql-connector得http://www.mysql.com/products/connector/这些就是mysql所谓的连接器吧.一路向下看到:C Wrapper for MySQL C API (MySQL) Download http:/…