密码学与签名
密码学相关知识
密码学是网络安全、信息安全、区块链等产品的基础,常见的非对称加密、对称加密、散列函数等,都属于密码学范畴。
密码学有数千年的历史,从最开始的替换法到如今的非对称加密算法,经历了古典密码学,近代密码学和现代密码学三个阶段。密码学不仅仅是数学家们的智慧,更是如今网络空间安全的重要基础。
现代密码学
① 散列函数
散列函数,也见杂凑函数、摘要函数或哈希函数,可将任意长度的消息经过运算,变成固定长度数值,常见的有MD5、SHA-1、SHA256,多应用在文件校验,数字签名中。
MD5 可以将任意长度的原文生成一个128位(16字节)的哈希值
SHA-1可以将任意长度的原文生成一个160位(20字节)的哈希值
② 对称密码
对称密码应用了相同的加密密钥和解密密钥。对称密码分为:序列密码(流密码),分组密码(块密码)两种。流密码是对信息流中的每一个元素(一个字母或一个比特)作为基本的处理单元进行加密,块密码是先对信息流分块,再对每一块分别加密。
例如原文为1234567890,流加密即先对1进行加密,再对2进行加密,再对3进行加密……最后拼接成密文;块加密先分成不同的块,如1234成块,5678成块,90XX(XX为补位数字)成块,再分别对不同块进行加密,最后拼接成密文。前文提到的古典密码学加密方法,都属于流加密。
③ 非对称密码
对称密码的密钥安全极其重要,加密者和解密者需要提前协商密钥,并各自确保密钥的安全性,一但密钥泄露,即使算法是安全的也无法保障原文信息的私密性。
在实际的使用中,远程的提前协商密钥不容易实现,即使协商好,在远程传输过程中也容易被他人获取,因此非对称密钥此时就凸显出了优势。
非对称密码有两支密钥,公钥(publickey)和私钥(privatekey),加密和解密运算使用的密钥不同。用公钥对原文进行加密后,需要由私钥进行解密;用私钥对原文进行加密后(此时一般称为签名),需要由公钥进行解密(此时一般称为验签)。公钥可以公开的,大家使用公钥对信息进行加密,再发送给私钥的持有者,私钥持有者使用私钥对信息进行解密,获得信息原文。因为私钥只有单一人持有,因此不用担心被他人解密获取信息原文。
对称加密算法
采用单钥密码系统的加密方法,同一个密钥可以同时用作信息的加密和解密,这种加密方法称为对称加密,也称为单密钥加密。
常见加密算法
DES : Data Encryption Standard,即数据加密标准,是一种使用密钥加密的块算法,1977年被美国联邦政府的国家标准局确定为联邦资料处理标准(FIPS),并授权在非密级政府通信中使用,随后该算法在国际上广泛流传开来。
AES : Advanced Encryption Standard, 高级加密标准 .在密码学中又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准。这个标准用来替代原先的DES,已经被多方分析且广为全世界所使用。
特点
• 加密速度快, 可以加密大文件
• 密文可逆, 一旦密钥文件泄漏, 就会导致数据暴露
• 加密后编码表找不到对应字符, 出现乱码
• 一般结合Base64使用
iOS 证书文件类型
.certSigningRequest
点击mac OS的钥匙串访问里的 证书助理 -> 从证书颁发机构请求证书,最后会创建出一个.certSigningRequest文件,其实这个过程就是创建了一对公私钥
- 其中.certSigningRequest文件保存着
- 申请者信息申请者的公钥
- 摘要算法
- 公钥加密算法
- 私钥保存在 keychain 中
.p12
在mac OS
的钥匙串访问
里选择一张证书,右击该证书,选择导出"xxxxx"
,然后设置密码,可以导出该证书对应的.p12
文件。.p12
文件包含个人信息、公钥和私钥,也就是证书 + 私钥
。iOS类型的每种证书同时存在数量有限制,而证书是依靠mac OS
上的.certSigningRequest
文件创建的,所以正常情况下,每种类型的证书只能在有限的Mac电脑上使用,如果需要在更多不同的Mac电脑上进行App开发、测试、签名,可以导出对应.p12
文件代替证书来使用。
Provisioning Profile
Provisioning Profile的文件格式为.mobileprovision,里面包含着
- 可以使用的证书
- App ID,由 TeamID 和 BundleID 组合而成,类似于 A1B2C3D4.com.domain.appName 形式
- 可安装该App的设备列表的UDID
- Entitlements,授权文件,列出了App可以进行哪些行为
- 以上信息的签名
在苹果开发网站上手动创建,或者使用Xcode自动创建。
.ipa
.ipa文件是iOS上的App安装文件,其实它只是一个压缩包,等同于.zip格式,用mac OS自带的归档实用工具可以直接对它解压,可以看到里面的内容
Code Signing
正常情况下(非越狱),所有App想要安装到iOS设备上,只有以下几种方法
- 非App Store
- 真机调试
- Ad-Hoc
- In-House
- App Store
无论是哪一种方法,都需要先把iOS项目编译成.app
文件,然后进行签名。按照惯例,需要分析一下Code Signing
非App Store
对于非App Store获得的.ipa
文件,需要严格复杂的签名和验证流程
- 创建.certSigningRequest文件,这时候会生成一对公私钥,这里称为公钥L(L:Local),私钥L。.certSigningRequest文件保存着公钥L
- iOS 以及 mac OS上的AppleWWDRCA.cer 证书保存的就是苹果的公钥A(A:Apple),而对应的私钥A则在苹果的后台
- 在苹果开发者网站上创建证书的时候,上传.certSigningRequest文件其实就是把公钥L传到苹果后台,用苹果后台里的私钥A去签名公钥L,得到对应的证书,把证书下载回来双击安装,会跟对应的私钥L绑定一起保存在keychain中
- 除了证书,还需要对应的Provisioning Profile。在苹果开发者网站上:
- 当需要把一个App安装在iOS设备上时,都会先把iOS项目编译打包成.app文件,而打包成可安装在iOS设备上的.app文件的前提是,设置该App的Provisioning Profile,最后使用合法的证书对源代码编译后的各种文件进行签名,步骤如下:
- 把.ipa文件或者.app文件安装在iOS设备上时
- 设置App的Bundle ID
- 设置可安装该App的设备UDID
- 设置该App的权限
- 设置可以使用的证书
- 最后会使用私钥A把以上这些数据进行签名,组成一个Provisioning Profile,格式为.mobileprovision,下载回来双击安装,会保存在~/Library/MobileDevice/Provisioning Profiles中,文件名为它的UUID
- 用mac OS里的公钥A验证Provisioning Profile,获取里面的信息
- 用Provisioning Profile里面的信息验证App的Bundle ID是否对应,App的权限是否对应
- 用公钥A验证Provisioning Profile里面的证书,再判断是否有其中一张证书在这台Mac电脑里
- 如果上面的验证都通过了,则会从mac OS的keychain 中取出符合条件且最新创建的证书,拿到对应的私钥L
- 如果有.framework文件、.dylib文件、插件、watch目录下的extension,对它们分别进行签名
- 把Provisioning Profile改名为embedded.mobileprovision放在.app文件里面
- 使用私钥L对整个.app文件进行签名,得到签名信息CodeResources也放会在.app文件里面
- 如果需要生成.ipa文件,则会把.app文件放在Payload文件夹里,把Payload文件夹和一些其他信息文件(非必要),一起压缩形成一个.ipa文件
- 先使用iOS设备上的公钥A对.app文件里面的embedded.mobileprovision文件进行验证,获取里面的证书
- 再使用公钥A对embedded.mobileprovision文件里面存在的证书进行验证,取出一张对应的证书,得到公钥L
- 使用公钥L对.app里面所有签名信息进行验证,如果验证通过,证明该.app文件是完整合法,没有被篡改的
- 获取embedded.mobileprovision文件里面的可安装该App的设备UDID列表,判断该iOS设备是否可以安装
- 如果前面的验证都通过,则App会安装在iOS设备上
流程说明二:
- 在你的 Mac 开发机器生成一对公私钥,这里称为公钥L,私钥L。L:Local
- 苹果自己有固定的一对公私钥,跟上面 AppStore 例子一样,私钥在苹果后台,公钥在每个 iOS 设备上。这里称为公钥A,私钥A。A:Apple
- 把公钥 L 传到苹果后台,用苹果后台里的私钥 A 去签名公钥 L。得到一份数据包含了公钥 L 以及其签名,把这份数据称为证书。
- 在开发时,编译完一个 APP 后,用本地的私钥 L 对这个 APP 进行签名,同时把第三步得到的证书一起打包进 APP 里,安装到手机上。
- 在安装时,iOS 系统取得证书,通过系统内置的公钥 A,去验证证书的数字签名是否正确。
- 验证证书后确保了公钥 L 是苹果认证过的,再用公钥 L 去验证 APP 的签名,这里就间接验证了这个 APP 安装行为是否经过苹果官方允许。(这里只验证安装行为,不验证APP 是否被改动,因为开发阶段 APP 内容总是不断变化的,苹果不需要管。)
App Store
当需要在App Store发布App时,则先需要把.ipa
文件上传到App Store。苹果会用一种非常简单的方式进行重新签名,这是因为在把.ipa
文件上传到App Store之前,会先进行类似于上面步骤的一系列验证,只有通过验证才会上传成功,所以这已经进行过一次复杂的验证,代表苹果已经认同了这个.ipa
文件,而用户又是从App Store下载的,所以也保证了.ipa
文件来源是权威的,最后只需要在用户设备上进行简单的验证就可以
- 苹果用私钥A对.app文件里面需要签名的文件进行重新签名
- 用户下载App Store上面的.ipa文件进行安装时,用iOS设备上的公钥A对.app文件里所有签名信息进行验证,如果验证通过,则会安装在iOS设备上