当前位置:科学 > 正文

iOS签名校验那些事儿

2023-01-26 15:41:47  来源:闪念基因

导读:iOS签名校验机制是苹果生态安全的基础,日常工作中无论是开发阶段还是测试阶段常常会遇到很多需要通过签名机制解决的问题,了解iOS签名机制的原理有助于提高我们解决相关问题的成本和效率。本文首先介绍数字签名和证书的原理,之后会介绍苹果开发者证书的生成安装过程,最后对苹果实现签名校验的流程及流程中涉及的关键信息进行介绍,希望能对大家有所帮助。


(资料图片)


全文9494字,预计阅读时间24分钟。


背景


iOS15 beta版发布后,QA同学需要测试新功能在iOS 15系统下的功能稳定性,但是通过公司流水线打出的企业包无法安装在 iOS 15系统的设备上,具体报错见下图:



通过在控制台查看安装过程中的具体报错信息,发现具体的IPA包的签名信息在iOS 15系统上已经不再被支持了: The code signature version is no longer supported.详细的控制台报错信息如下图所示:



也就是安装失败和IPA的代码签名版本有关,为此通过codesign命令查看流水线产出的IPA的相关签名信息,具体信息见下图,其中CodeDirectory的版本为v=20400



CodeDirectory直译是代码目录,记录的是将 Mach-O文件分页后每页的哈希值信息,除此之外还包含了资源文件的摘要信息、权限信息等,这些信息按照一定的格式组合在一起,而不同的 signature version对应着不同的信息种类、组合形式或计算算法。去年从iOS 14 beta2开始,苹果系统采用一种更为安全的签名格式,在其上运行使用旧签名格式签名的APP时会出警告弹窗。其官方介绍中提到 In a future release, the new format will become mandatory, and the system won’t launch apps with the old signature format.因此怀疑是签名格式在 iOS 15系统上进行了强制校验,导致安装失败:



在官方文档中提到 If you signed your app on a Mac running macOS 10.14 or later, the app already has the new signature format.换句话说 macOS系统的版本会影响到签名的格式; "For any value of v less than 20400, you’ll need to re-sign your app."


CodeDirectory version的值小于 20400时可以通过重签名来解决签名失效问题。而CodeDirectory v=20400可以安装在iOS 14系统上,但是却无法安装在iOS 15系统上。为了解决这个问题,采用重签名的思路,在macOS 11.5.2macOS 12.0 Beta版系统下分别对流水线 IPA包重签名后,均可以正常安装在 iOS 15系统上了。


以上是 iOS签名校验机制的一个体现,日常开发及测试中,与上述 iOS签名校验机制相关的事情还有很多比如修改系统时间后使得企业证书过期从而导致启动崩溃等,在这里再和大家一起分享下有关 iOS证书与签名校验相关的一些信息。


首先我们看几个问题:


什么是签名校验机制?

对可执行文件或脚本进行数字签名,用来保证软件在签名后未被损害或者修改的措施;


苹果为什么要使用签名校验机制?

Signing your app allows iOS to identify who signed your app and to verify that your app hasn’t been modified since you signed it.

即确定APP来源并防止外部攻击,以实现苹果对其生态的控制;


苹果如何实现签名校验?


这是 iOS签名校验机制的流程示意图,在学习过程中,个人觉得理解清楚非对称加密、数字签名以及数字证书的原理对于理解整个签名机制非常重要,因此在文章的开始会对加密与解密、数字签名以及数字证书做一些说明,然后结合数字签名和证书的原理,对苹果创建开发者证书的流程以及 iOS签名校验流程包括过程中涉及到一些关键信息进行说明:


1. 加密与解密、数字签名、证书在通信过程中各自的作用

2. 解析苹果开发者证书的生成安装过程

3. 苹果实现签名校验的流程及关键信息


一、加密与解密、数字签名、证书在通信过程中各自的作用


无论是从 AppStore下载 App安装到手机上还是在Debug阶段通过XcodeApp安装到测试机上进行真机调试,其实都是一次将 App包发送到手机沙盒中的一次通信过程,如何保证一次安全有效的通信呢?或者说在一次通信过程中可能面临哪些安全问题呢?



1.1 防止被窃听 - 加密与解密


通信过程中是不好避免被第三方拦截的,但是我们可以做到即便被截获,窃听者仍然无法破译有效的信息,这个过程可以通过加密来实现。


目前加密算法主要有两大类,对称加密和非对称加密:

对称加密的特点是加密和解密使用的同一个秘钥,其特点是速度快,常用算法有: DES3DESAES

非对称加密的密钥分为公钥和私钥,其最重要的特性是使用公钥加密的信息,只能使用私钥解密,而使用私钥加密的信息,只能使用公钥进行解密,最常用的算法有 RSA


但是对称加密的密钥管理繁琐且密钥传输存在一定的安全隐患,而非对称加密算法速度比较慢,尤其是对于加密数据较大的信息时耗时更加明显。因此在实际使用过程中,最常使用的是混合加密方式:

发送方:1.对信息(明文)采用DES密钥加密;2.使用RSA加密前面的DES密钥信息;然后将1和2步产生的信息进行整合后传递。



接收方:接收到信息后:1.用RSA解密DES密钥信息;2.再用RSA解密获取到的密钥信息解密密文信息;最终就可以得到我们要的信息(明文)。



1.3 防止否认 - 数字签名


因为公钥是对外公开的,A可以使用公钥加密信息计算摘要,B也可以使用公钥加密信息计算摘要,也就是所有拥有公钥的人都可能成为信息发送者,这就导致A发送消息后可以否认。前面我们有提到非对称加密的特性:使用公钥加密的信息,只能使用私钥解密,而使用私钥加密的信息,只能使用公钥进行解密。公钥是对外公开的,但是私钥仅存在于密钥对生成者自己手里,所以当在发送消息时使用发送者的私钥加密信息,在接收端使用发送者的公钥来解密信息,那么接收端就可以精确确认消息发送者了,也就解决了消息发送者否认发送的问题。使用发送者的私钥对摘要进行加密,就形成了签名,即数字签名


我们来看下数字签名是如何起作用的:


总结下数字签名的作用,主要有三点:1.可以确认消息的完整性;2.可以识别消息是否被篡改;3.可以防止消息发送者否认;


但是我们不能忽视一点:数字签名生效的前提:用于加密的公钥必须属于真正的接受者,用于解密的公钥必须属于真正的发送者。如果公钥被伪造了或者说好事者冒充发送者去发送消息,单纯依赖数字签名是无法解决的;我们一起来看下公钥被伪造时会发生什么:



由上图可以看到,如果公钥在传输过程中被伪造了,那么后续相关的通信过程都是建立一个伪造的密钥对间进行,从而导致这个通信过程不再安全。因此在验证签名之前,首先得先验证公钥的合法性。


但是如何保证公钥的合法性呢?

根据上面的相关介绍,为了保证公钥信息不被篡改和欺骗,那么最好的方式就是对公钥进行数字签名,但问题又来了,如何保证此次数字签名验证过程中公钥的合法性呢?再来一次数字签名吗?这就陷入了一个鸡生蛋蛋生鸡的过程了,为了打破这个死循环,人们创造了证书中心和数字证书


1.4.保证公钥的合法性 - 数字证书


循环进行数字签名的原因是因为公钥有可能被伪造,为此人们将一些具有公信力的组织或者政府部门作为证书中心,由证书中心使用自己的私钥来对公钥进行数字签名。通俗理解证书中心就是那些能够认定“公钥确实属于此人”并且能够生成数字签名的权威个人或者组织,简称CA。而由CA对公钥等信息施加数字签名后就生成了证书。


我们一起看下数字证书是如何起作用的:



消息接收者首先生成密钥对,并将公钥_B及邮箱等信息在CA认证机构中进行注册,认证机构CA用自己的私钥_CA公钥_B进行数字签名,并生成证书;消息发送者A向认证机构CA请求证书,并通过认证机构CA公钥_CA验证数字签名,以验证公钥_B的合法性。


对此,我们对公钥、私钥、数字签名、数字证书的概念及作用有了一个大概的回顾。下面我们从数字签名及数字证书的生成流程角度来看下iOS开发者证书的生成与安装过程。


二、苹果开发者证书的生成与安装


-1.生成证书请求:钥匙串访问 -> 证书助理 -> 从证书颁发机构请求证书 (可以理解为Mac端创建非对称加密密钥对公钥M私钥M的过程,使用私钥M来签署生成CSR文件,CSR文件中包含开发者的信息和公钥M私钥M则存储在Mac端本地)



-2.登录开发者平台,将第一步生成的CertificateSigningRequest.certSigningRequest上传至Developer生成证书。(CertificateSigningRequest.certSigningRequest可以理解为Mac生成的公钥,上传至开发者平台可以为将公钥M在证书认证机构CA进行注册,并利用苹果开发者中心的公钥AMac设备的公钥进行签名,生成开发者证书)



- 3.Mac将证书下载到本地,双击安装(在安装过程中,钥匙串keychain会将第一步生成的私钥M与第二步生成的Cer证书关联在一起:



三、苹果实现签名校验的流程及关键信息


苹果签名校验机制的作用是要保证每一个安装到iOS设备上的App都是经过苹果官方授权的。为了实现上述效果,苹果采取的方案是双重签名,其大概流程可以参见下图:



那是不是只要拥有一个经过苹果认证的开发者证书,就可以将任意App安装在任意测试机上呢?显然这是苹果生态所不允许的。那苹果是通过什么方式实现设备限制的呢?而且,在团队开发中,也并不是所有人都去生成开发者证书,那又是通过什么方式实现团队授权的呢?以及在苹果开发者中心中配置的BundleIDCapabilitiesDevices等信息在签名机制中又扮演着什么样的作用呢?


3.1 关于P12 - 团队协作开发

在上面的签名过程中,我们看到开发者在对App进行签名过程中,主要用到两个信息:私钥M和证书,因此只需要将这两个信息提供给团队中的其它成员。在证书安装过程我们了解中,钥匙串会将证书与Mac生成的私钥M进行关联并存储为钥匙串中的一项,钥匙串支持将其导出为p12文件,然后我们将p12文件提供给团队成员安装就可以了。



3.2 关于Entitlements - 权限管控


Xcode在编译打包时会自动执行/usr/bin/codesign命令进行代码签名,以下是签名的详细信息:



在签名时通过--sign指定了证书信息,那么--entitlements配置的是什么信息呢?

entitlements链接:

(https://developer.apple.com/library/archive/technotes/tn2415/_index.html)


An Entitlement can be thought of as the string written into an app"s signature that allows a specific capability or opts the app into a specific service. The operating system (OS) checks these strings before allowing an app access to certain features. For example, an app must have the iCloud entitlement before it is allowed to access iCloud APIs at runtime.


简单来说entitlements其实就是iOS沙盒环境的配置文件,苹果通过entitlements文件来管控一个App所能使用的服务和权限。Sandbox(沙盒)是iOS安全体系中很重要的一环,沙盒不仅仅使App间相互独立,同时也对每个App可操作的行为进行了管控,比如可以使用哪些敏感的系统能力(PushSign in with apple等)等。Xcode会默认生成一个包含有Team ID信息和App ID信息的权限声明,如果在XcodeSigning&Capabilities中开启了相关权限,那么会显式的生成一个后缀名为.entitlements的配置文件,里面包含了相关权限信息的说明。在--entitlements选项后面的文件是在.entitlements的配置文件基础上增加了默认配置后的信息。在Xcode签名时,会将该权限信息文件嵌入到二进制代码中,作为被签名内容的一部分,由代码签名保证其不会被篡改。  


可通过 security cms -D -i /path/to/iOSTest.mobileprovision来检查本地的 Provisioning Profile是否包含所需要的权限。


3.3 关于Provisioning profile


Provisioning profile act as a link between the device and the developer account. During development, you choose which devices can run your app and which app services your app can access. A provisioning profile is downloaded from your developer account and embedded in the app bundle, and the entire bundle is code-signed.


Provisioning Profile是一个由苹果证书中心加密签名的一个plist文件,包含有与之绑定的App ID、设备的UUID列表、过期时间、TeamIDentilements等信息以及用于对应用程序进行签名的证书,是苹果用来解决对设备授权以及管控APP敏感权限的解决方案。其在证书中心的配置页面如下:



在证书中心配置完App IDUnique Device Identifiers以及capabilities等信息后,苹果证书中心会将这些信息与证书一起使用苹果的私钥进行签名,最后将签名信息与配置信息、证书、签名信息一起组成一个Provisioning Profile文件。开发者将其下载并安装,默认情况下Xcode会自动帮助开发者进行管理。以下是Xcode中安装的Provisioning Profile信息:



Mac编译完一个App后,会将Provisioning Profile文件也打包进App中,并将文件命名为embedded.mobileprovision。在App安装到iOS设备上时,iOS设备会通过预置的公钥信息来验证embedded.mobileprovision的签名合法性,进而验证证书中的签名是否正确。


确保了embedded.mobileprovision里的数据都是苹果授权以后,就可以使用其中的信息来校验本次安装的合法性,使用公钥A验证Mach-O的签名信息、验证证书的签名及有效期、验证设备ID是否在设备列表中、Provisioning Profile中的App ID是否与BundleID是否匹配等等;


值得注意的一点是:设备列表只在Development证书下生效,因为EnterpriseDistribution证书本身就是要求可以任意安装,所以不受设备列表的限制;过期时间只对DevelopmentEnterprise证书生效,Distribution证书下不受限制,这也是当DevelopmentEnterprise证书过期后会导致应用无法安装或无法启动,而从App Store下载的应用不会有时间限制。


当然在开发者中心可以随时对Provisioning Profile进行修改,更新不会对已有Provisioning Profile产生影响。


3.4 关于可执行文件与资源的签名


在编译生成App的过程中,Xcode会通过钥匙串找到与配置证书配对的私钥M对二进制文件进行签名,并将签名信息嵌入到可执行二进制文件中,用于在安装时确认Mach-O文件是否有被修改。可通过MackOView验证:



但是App中不仅仅包含二进制文件,还包含一系列诸如图片、音视频文件等预置资源,因此通过单一的对二进制文件进行签名不足以保证整个App文件的完整性和有效性。在iOS中,应用程序使用遵循shallow application bundles结构的目录来存储必要资源和数据信息,大致为:


以下是一个非常简单的IPA包的包结构:



可以看到为了保证可执行文件及其在运行期间所依赖的数据和资源不被篡改,在实际生成的APP包中,会新生成一个_CodeSignature目录,在该目录下包含一个名为CodeResources文件,该文件为plist类型的文件,里面包含了App下除可执行文件外其它文件的信息,key通常为文件名,value通常为其摘要信息。里面会有filesfiles2两项,其中files保存的是每个文件的sha1的值,files2同时保存了sha1sha256,主要原因是sha1存在不安全性。_CodeSignature/CodeResources文件的主要作用是记录签名后每个文件的哈希值,以在安装时用来确保对应的文件没有被篡改过。


3.5 签名及校验流程



> 1.首先在Mac端生成一对密钥对(公钥M和私钥M),苹果系统本身也会生成一对密钥对(公钥A和私钥A),其中公钥A预置在iOS设备上,私钥A放在苹果服务器中;

> 2.开发者将公钥M整合在csr文件中通过开发者后台上传至苹果服务器,苹果服务器使用私钥A对公钥M进行数字签名生成证书;同时使用私钥A将证书、AppIDentilements、设备UDIDs等信息加密生成Provisioning Profile文件;对应的开发者下载证书和Provisioning Profile文件并安装在Mac中。安装过程中会将证书与私钥M进行关联,Xcode默认会对Provisioning Profile文件进行管理。

> 3.在开发过程中,会使用私钥M对App进行签名,同时会将Provisioning Profile文件也打包进App中即embedded.mobileprovision文件。

> 4.当将iOS设备与Xcode连接并通过身份验证后,Xcode会将App数据传输到iOS设备中,iOS设备此时并不会创建真正的沙盒环境来运行App,而是会在一个临时沙盒环境中来存放陆续收到的数据,一旦全部接收完,iOS系统首先会使用预置的公钥A对embedded.mobileprovision文件的签名进行验证,已确认App来源是否合法;来源合法性验证通过后,便可使用公钥M去验证里面证书的签名信息、验证该设备ID是否在对应UUID列表中、以及APP中的权限开关配置是否和embedded.mobileprovision文件中配置的entilements信息相吻合等;同时会读取_CodeSignature/CodeResources中的信息对资源文件进行校验。只有全部经过验证后,才会为App创建真正的沙盒环境进行安装。在启动APP时,系统也会执行相应的启动校验,以防止安装后进行的修改。


参考文献:

作者:梅花禄

来源:微信公众号:百度Geek说

出处:https://mp.weixin.qq.com/s/BArq0CEAQ90ZQh6xC5pNSw

关键词: 2019科技之光 苹果公司 脚本语言 Store

推荐阅读

iOS13正式版推送 iOS13正式版推送值得更新吗?

苹果发布iOS13 5,iOS和iPadOS13 5系统正式版发布,系统新增加了多项功能,用户在安装了正确的开发人员配置文件后可以从Apple开发人员中心 【详细】

虎门大桥怎么样了 虎门大桥没有问题可以恢复通车了吗?

关于虎门大桥已经连续几天成为热门话题了,5月5日,最开始为了保障安全,对交通实行双向封闭。5月10日,组织报告测评,而今天根据官方消息 【详细】

2025年取消燃油车 2025年取消燃油车是真的吗?

相信很多人都听说过中国2025年取消燃油车,接下来小编就带大家介绍一下相关知识,大家可以了解一下。汽车一般使用汽油、柴油等化石燃料作为 【详细】

未成年打赏可退还是真的吗?未成年打赏可退有什么法律依据?

今日,未成年打赏可退还的消息引发人们的热切讨论,未成年人网络打赏引发的纠纷,多年来成为人们关注的社会热点问题,那么未成年打赏可退还 【详细】

首都第二国际机场在哪里 首都第二国际机场为何选址大兴?

首都第二国际机场为何选址大兴?大兴位于北京的南部,为什么选在南边建设机场?现在北京机场有几个?为了确保首都的安全,南部修建了北京第二 【详细】

关于我们  |  联系方式  |  免责条款  |  招聘信息  |  广告服务  |  帮助中心

联系我们:85 572 98@qq.com备案号:粤ICP备18023326号-40

科技资讯网 版权所有