iOS app开发过程中,真机调试,测试分发,以及正式发布到appStore上,以上所说都离不开证书,开发证书,发布证书,推送证书。那么证书是怎么回事呢?我们首先得从加密说起。
我们知道加密分为对称加密和非对称加密。对称加密就是,一把密钥既能加密也能解密;非对称加密是私钥加密,公钥解密(或者公钥加密,私钥解密)。今天我们所说的数字证书签名,涉及的就是非对称加密RSA。
1、RSA原理:
1.1、质数和互质关系:
质数:又称素数,指在一个大于1的自然数中,除了1和此整数自身外,不能被其他自然数整除的数。例如1,3,5,7,11等。
互质关系:对于N个自然数,他们的公因数只有1,则成N个数互质。例如:7和8,3和4,3和5等。我们可以得出结论:a、1和任何整数互质;b、相邻的两个自然数互质;c、两个质数互质。
1.2、欧拉定理:
欧拉函数:对于正整数N,代表小于等于N的与N互质的数的个数,记作φ(N)。
例如:对于正整数8,小于8的并与8互质的数有:1、3、5、7,即φ(8) = 4;
对于正整数16,小于12的并与12互质的数有:1、3、5、7、9、11、13、15,即φ(16) = 8;
欧拉定理还有几个引理,具体如下:
1⃣️、对于质数p,则φ(p) = p-1;很好证明,质数的概念就是规定,质数只能被1和本身整除。
2⃣️、如果a为某一个素数p的幂次,那么φ(p^a)=(p-1)*p^(a-1),证明:
小于p^a的整数的个数为p^a-1,这里能被p整除的数的个数为p^(a-1)-1,即可以得出φ(p^a) = p^a-1 -(p^(a-1)-1)= p^a - p^(a-1) = (p-1)*p^(a-1),得证。
3⃣️、如果两个互质数a、b,则φ(p1*p2) = φ(p1)*φ(p2)。如果a与p1互质(a<p1),b与p2互质(b<p2),c与p1p2互质(c<p1p2),则c与数对 (a,b) 是一一对应关系。由于a的值有φ(p1)种可能,b的值有φ(p2)种可能,则数对 (a,b) 有φ(p1)φ(p2)种可能,而c的值有φ(p1p2)种可能,所以φ(p1p2)就等于φ(p1)φ(p2)。
例如φ(12) = φ(3*4) = φ(3)*φ(4) = 2*2 = 4 (1,5,7,11)
φ(42) = φ(6*7) = φ(6)*φ(7) = 2*6 = 12(1,5,11,13,17,19,23,25,29,31,37,41)
4⃣️、如果p1、p2、p3、p4。。。pk为质数,n = (p1^a1)* (p2^a2)* (p3^a3)...* (pk^ak),
则φ(n) = n*(1-1/p1)*(1-1/p2)*……*(1-1/pk),可以根据2⃣️3⃣️得出。
欧拉定理:若正整数 a , n互质,则 a^φ(n)≡1(mod n) 。即a的φ(n)次方减1始终能被n整除。比如,3和7互质,而7的欧拉函数φ(7)等于6,所以3的6次方(729)减去1,可以被7整除(728/7=104)。
费马小定理:根据欧拉定理及当n为质数时,可以写成a^(p-1)≡1(mod p)。
模反元素:如果两个正整数a和n互质,那么一定可以找到整数b,使得 ab-1 被n整除,或者说ab被n除的余数是1,这是b叫做a的模反元素:即 a*b ≡ 1(mod n).
中国剩余定理推论:如果 p, q 互质,n = p * q,则对任意整数 x 和 a:
即要证明x与a关于n同余,相当于证明x与a关于p和q都同余。
1.3、加密算法:
1.3.1、 密钥生成算法
a、随机生成两个素数 p,q,计算 n=pq,计算欧拉函数 φ(n)=(p−1)(q−1);
b、选取一较小且与φ(n)互质的正整数e。那么(n, e)为密钥对中的公钥;
c、计算e在模φ(n)下的数论倒数d,e*d ≡ 1(modφ(n)),那么(n, d)为密钥对中的私钥。
1.3.2、加密算法
其中M为明文,(n, e)为公钥,C为密文
1.3.3、解密算法
其中C为密文,(n, d)为私钥,M为明文
根据加密、解密过程中n、e、d三数扮演的角色,我们把n称为公共模数,把e称为公共指数,把d称为私有指数。
1.3.4、证明过程:
M =( M^e (mod n ))^d (mod n) = M^ed (mod n);
M^(ed) ≡ M(mod n), 根据剩余定理推论,只需要证明M^(ed) ≡ M(mod p)和M^(ed) ≡ M(mod q),
M^(k*φ(n) + 1) (mod p)=M^(k*(p-1)*(q-1) + 1)(mod p)=M*(M^(p-1))^k*(q-1))(mod p)=M*(1)^k*(q-1))(mod p) = M(mod p).
同理可证M^(ed) ≡ M(mod q)。
2、数字签名:
2.1、数字签名的过程:
模拟下数据传递过程,客户端A传数据给服务端B:
a、如果直接明文传递,裸传,风险最大,例如http,很容易被抓包;
b、后面有专门的Hash算法(专门是用来识别信息的),如果加上Hash算法,将明文跟Hash值传过去,对方收到后可以拿出HASH值来进行验证。如果Hash算法泄漏了,同样不安全,也很容易被篡改。
c、所以这里我们要对数据进行加密.明文数据有时会比较大,不适合使用RSA非对称加密算法,那么数据的HASH值是比较小的。然后客户端A将签名后的数据跟明文一起传给服务端B,具体的过程如下:
2.2、数字签名的验证过程
当对方拿到数据之后,如何进行验证呢?
a、服务端B收到原始的数据和数字签名后,先进行校验.拿到原始数据,通过同样的HASH算法得到数据的HASH值.
b、通过非对称加密,将数字签名中的校验HASH值解密出来.
c、对比两个HASH值是否一致.这样可以很好的判断数据是否被篡改,具体如下:
3、代码签名:
在iOS出来之前,主流的操作系统(Mac/Windows)软件随便从哪里下载都能运行,系统安全存在隐患,盗版软件,病毒入侵,静默安装等等。苹果为了解决这样的风险,保证每个安装app都经过了苹果的授权验证,就有了代码签名。
根据上面数字签名的过程,我们能够想到,就是苹果需要生成两把钥匙,私钥放到苹果的服务器,公钥放到苹果系统,即每个设备都有,app上传到AppStore后,苹果服务器用私钥对代码进行签名,用户从AppStore下载app后,首先用公钥对代码进行签名验证过程,验证通过才能进行安装,这就是最简单的代码签名,但是不是所有的app都是从AppStore上分发的,比如开发者需要实时的run在手机上,没经过苹果的服务器,而苹果对这个过程也需要监控,所以简单的代码签名是不能满足需求的。实际上苹果运用了另一套签名机制,即双重签名。
双重签名过程:
我们知道,从事app开发的,如果要run到真机上,或者发不到appstore,或者通过蒲公英等其他分发网站,第一步都是需要去苹果官网申请证书,包括开发证书和发布证书。
申请证书的过程:
首先我们从证书机构申请拿到CSR文件,其实这个CSR文件,包括公钥M 以及一些开发者的信息,而公钥M是来自MAC系统,在Mac系统中生成非对称加密算法的一对公钥\私钥(你的Xcode帮你代办了).这里称为公钥M 私钥M . M = Mac
拿到CSR文件后,到Apple developer官网申请证书,上面讲过,iOS系统也有一对非对称加密钥匙,公钥A在iOS系统,私钥A在apple后台,苹果后台拿到CSR文件后,会用私钥A对CSR文件里面的公钥M的hash值进行签名,然后跟上传的其他信息,打包生成证书文件,开发者通过下载拿到该证书,就可以进行代码打包分发,过程如下:
而打包过程就是编译完app后,通过MAC系统的私钥M对编译后的代码的Hash值进行签名,然后将证书、签名的hash值、编译的代码一起打包进行分发,用户拿到app包安装到iOS系统,iOS系统,会先通过iOS的公钥A对证书里面的公钥M进行验证,验证通过,然后拿公钥M对代码签名进行验证,过程如下:
但是,上述这个过程就完美了么?那岂不是,一证在手,天下我有!!!已经介绍了简单的应用签名但是这种签名方式并不能解决应用滥用的问题,所以苹果又加了两个限制.第一限制在苹果后台注册过的设备才可以安装.第二限制签名只能针对某一个具体的APP.并且苹果还想控制App里面的iCloud/PUSH/后台运行/调试器附加这些权限,所以苹果把这些权限开关统一称为Entitlements(授权文件).并将这个文件放在了一个叫做Provisioning Profile(描述文件)文件中.描述文件是在AppleDevelop网站创建的(在Xcode中填上AppleID它会代办创建),Xcode运行时会打包进入APP内.
所以我们使用CSR申请证书时,我们还要申请一个东西!! 就是描述文件!!流程如下
当然,Provisioning profile本身也是通过签名认证的,所以别想着你可以更改里面的东西来达到扩充权限\设备的目的.只有老老实实的去网站向Apple申请一份权限更多\设备更多的profile。
整体的流程
首先我们总结一下刚才的一些名词
证书:内容是公钥或者私钥,由认证机构对其签名组成的数据包!我们开发可以使用钥匙串访问看到
P12:就是本地私钥,可以导入到其他电脑
Entitlements:权限文件,包含了APP一些权限的plist文件
CertificateSigningRequest:CSR文件包含了本地公钥的数据文件
Provisioning Profile:描述文件,包含了证书/Entitlements等数据,并由苹果后台私钥签名的数据包.
流程如下:
第 1 步对应的是 keychain 里的 “从证书颁发机构请求证书”,这里就本地生成了一对公私钥,保存的 CertificateSigningRequest 里面就包含公钥,私钥保存在本地电脑里.
第 2 步向苹果申请对应把 CSR 传到苹果后台生成证书.
第 3 步证书下载到本地.这时本地有两个证书.一个是第 1 步生成的私钥,一个是这里下载回来的证书,keychain 会把这两个证书关联起来,因为他们公私钥是对应的,在XCode选择下载回来的证书时,实际上会找到 keychain 里对应的私钥去签名.这里私钥只有生成它的这台 Mac 有,如果别的 Mac 也要编译签名这个 App 怎么办?答案是把私钥导出给其他 Mac 用,在 keychain 里导出私钥,就会存成 .p12 文件,其他 Mac 打开后就导入了这个私钥.
第 4 步都是在苹果网站上操作,配置 AppID / 权限 / 设备等,最后下载 Provisioning Profile 文件。
第 5 步 XCode 会通过第 3 步下载回来的证书(存着公钥),在本地找到对应的私钥(第一步生成的),用本地私钥去签名 App,并把 Provisioning Profile 文件命名为 embedded.mobileprovision 一起打包进去。所以任何本地调试的APP,都会有一个embedded.mobileprovision(描述文件)从App Store下载的没有.
以上就是iOS的数字证书签名,欢迎指正。
参考:iOS应用签名(下)