iOS app開發(fā)過程中,真機(jī)調(diào)試,測(cè)試分發(fā),以及正式發(fā)布到appStore上,以上所說都離不開證書,開發(fā)證書,發(fā)布證書,推送證書。那么證書是怎么回事呢?我們首先得從加密說起。
我們知道加密分為對(duì)稱加密和非對(duì)稱加密。對(duì)稱加密就是,一把密鑰既能加密也能解密;非對(duì)稱加密是私鑰加密,公鑰解密(或者公鑰加密,私鑰解密)。今天我們所說的數(shù)字證書簽名,涉及的就是非對(duì)稱加密RSA。
1、RSA原理:
1.1、質(zhì)數(shù)和互質(zhì)關(guān)系:
質(zhì)數(shù):又稱素?cái)?shù),指在一個(gè)大于1的自然數(shù)中,除了1和此整數(shù)自身外,不能被其他自然數(shù)整除的數(shù)。例如1,3,5,7,11等。
互質(zhì)關(guān)系:對(duì)于N個(gè)自然數(shù),他們的公因數(shù)只有1,則成N個(gè)數(shù)互質(zhì)。例如:7和8,3和4,3和5等。我們可以得出結(jié)論:a、1和任何整數(shù)互質(zhì);b、相鄰的兩個(gè)自然數(shù)互質(zhì);c、兩個(gè)質(zhì)數(shù)互質(zhì)。
1.2、歐拉定理:
歐拉函數(shù):對(duì)于正整數(shù)N,代表小于等于N的與N互質(zhì)的數(shù)的個(gè)數(shù),記作φ(N)。
例如:對(duì)于正整數(shù)8,小于8的并與8互質(zhì)的數(shù)有:1、3、5、7,即φ(8) = 4;
對(duì)于正整數(shù)16,小于12的并與12互質(zhì)的數(shù)有:1、3、5、7、9、11、13、15,即φ(16) = 8;
歐拉定理還有幾個(gè)引理,具體如下:
1??、對(duì)于質(zhì)數(shù)p,則φ(p) = p-1;很好證明,質(zhì)數(shù)的概念就是規(guī)定,質(zhì)數(shù)只能被1和本身整除。
2??、如果a為某一個(gè)素?cái)?shù)p的冪次,那么φ(p^a)=(p-1)*p^(a-1),證明:
小于p^a的整數(shù)的個(gè)數(shù)為p^a-1,這里能被p整除的數(shù)的個(gè)數(shù)為p^(a-1)-1,即可以得出φ(p^a) =?p^a-1 -(p^(a-1)-1)=??p^a -?p^(a-1) = (p-1)*p^(a-1),得證。
3??、如果兩個(gè)互質(zhì)數(shù)a、b,則φ(p1*p2) =?φ(p1)*φ(p2)。如果a與p1互質(zhì)(a<p1),b與p2互質(zhì)(b<p2),c與p1p2互質(zhì)(c<p1p2),則c與數(shù)對(duì) (a,b) 是一一對(duì)應(yīng)關(guān)系。由于a的值有φ(p1)種可能,b的值有φ(p2)種可能,則數(shù)對(duì) (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為質(zhì)數(shù),n = (p1^a1)*?(p2^a2)*?(p3^a3)...*?(pk^ak),
則φ(n) =?n*(1-1/p1)*(1-1/p2)*……*(1-1/pk),可以根據(jù)2??3??得出。
歐拉定理:若正整數(shù)?a , n互質(zhì),則?a^φ(n)≡1(mod n) ?。即a的φ(n)次方減1始終能被n整除。比如,3和7互質(zhì),而7的歐拉函數(shù)φ(7)等于6,所以3的6次方(729)減去1,可以被7整除(728/7=104)。
費(fèi)馬小定理:根據(jù)歐拉定理及當(dāng)n為質(zhì)數(shù)時(shí),可以寫成a^(p-1)≡1(mod p)。
模反元素:如果兩個(gè)正整數(shù)a和n互質(zhì),那么一定可以找到整數(shù)b,使得 ab-1 被n整除,或者說ab被n除的余數(shù)是1,這是b叫做a的模反元素:即 ? a*b ?≡ 1(mod n).
中國剩余定理推論:如果 p, q 互質(zhì),n = p * q,則對(duì)任意整數(shù) x 和 a: ??

即要證明x與a關(guān)于n同余,相當(dāng)于證明x與a關(guān)于p和q都同余。
1.3、加密算法:
1.3.1、?密鑰生成算法
a、隨機(jī)生成兩個(gè)素?cái)?shù) p,q,計(jì)算 n=pq,計(jì)算歐拉函數(shù) φ(n)=(p?1)(q?1);
b、選取一較小且與φ(n)互質(zhì)的正整數(shù)e。那么(n, e)為密鑰對(duì)中的公鑰;
c、計(jì)算e在模φ(n)下的數(shù)論倒數(shù)d,e*d ≡ 1(modφ(n)),那么(n, d)為密鑰對(duì)中的私鑰。
1.3.2、加密算法

其中M為明文,(n, e)為公鑰,C為密文
1.3.3、解密算法

其中C為密文,(n, d)為私鑰,M為明文
根據(jù)加密、解密過程中n、e、d三數(shù)扮演的角色,我們把n稱為公共模數(shù),把e稱為公共指數(shù),把d稱為私有指數(shù)。
1.3.4、證明過程:
? ?M =( M^e (mod n ))^d (mod n) = M^ed (mod n);
M^(ed)?≡ M(mod n), 根據(jù)剩余定理推論,只需要證明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、數(shù)字簽名:
2.1、數(shù)字簽名的過程:
模擬下數(shù)據(jù)傳遞過程,客戶端A傳數(shù)據(jù)給服務(wù)端B:
a、如果直接明文傳遞,裸傳,風(fēng)險(xiǎn)最大,例如http,很容易被抓包;
b、后面有專門的Hash算法(專門是用來識(shí)別信息的),如果加上Hash算法,將明文跟Hash值傳過去,對(duì)方收到后可以拿出HASH值來進(jìn)行驗(yàn)證。如果Hash算法泄漏了,同樣不安全,也很容易被篡改。
c、所以這里我們要對(duì)數(shù)據(jù)進(jìn)行加密.明文數(shù)據(jù)有時(shí)會(huì)比較大,不適合使用RSA非對(duì)稱加密算法,那么數(shù)據(jù)的HASH值是比較小的。然后客戶端A將簽名后的數(shù)據(jù)跟明文一起傳給服務(wù)端B,具體的過程如下:

2.2、數(shù)字簽名的驗(yàn)證過程
當(dāng)對(duì)方拿到數(shù)據(jù)之后,如何進(jìn)行驗(yàn)證呢?
a、服務(wù)端B收到原始的數(shù)據(jù)和數(shù)字簽名后,先進(jìn)行校驗(yàn).拿到原始數(shù)據(jù),通過同樣的HASH算法得到數(shù)據(jù)的HASH值.
b、通過非對(duì)稱加密,將數(shù)字簽名中的校驗(yàn)HASH值解密出來.
c、對(duì)比兩個(gè)HASH值是否一致.這樣可以很好的判斷數(shù)據(jù)是否被篡改,具體如下:

3、代碼簽名:
在iOS出來之前,主流的操作系統(tǒng)(Mac/Windows)軟件隨便從哪里下載都能運(yùn)行,系統(tǒng)安全存在隱患,盜版軟件,病毒入侵,靜默安裝等等。蘋果為了解決這樣的風(fēng)險(xiǎn),保證每個(gè)安裝app都經(jīng)過了蘋果的授權(quán)驗(yàn)證,就有了代碼簽名。
根據(jù)上面數(shù)字簽名的過程,我們能夠想到,就是蘋果需要生成兩把鑰匙,私鑰放到蘋果的服務(wù)器,公鑰放到蘋果系統(tǒng),即每個(gè)設(shè)備都有,app上傳到AppStore后,蘋果服務(wù)器用私鑰對(duì)代碼進(jìn)行簽名,用戶從AppStore下載app后,首先用公鑰對(duì)代碼進(jìn)行簽名驗(yàn)證過程,驗(yàn)證通過才能進(jìn)行安裝,這就是最簡單的代碼簽名,但是不是所有的app都是從AppStore上分發(fā)的,比如開發(fā)者需要實(shí)時(shí)的run在手機(jī)上,沒經(jīng)過蘋果的服務(wù)器,而蘋果對(duì)這個(gè)過程也需要監(jiān)控,所以簡單的代碼簽名是不能滿足需求的。實(shí)際上蘋果運(yùn)用了另一套簽名機(jī)制,即雙重簽名。
雙重簽名過程:
我們知道,從事app開發(fā)的,如果要run到真機(jī)上,或者發(fā)不到appstore,或者通過蒲公英等其他分發(fā)網(wǎng)站,第一步都是需要去蘋果官網(wǎng)申請(qǐng)證書,包括開發(fā)證書和發(fā)布證書。
申請(qǐng)證書的過程:
首先我們從證書機(jī)構(gòu)申請(qǐng)拿到CSR文件,其實(shí)這個(gè)CSR文件,包括公鑰M 以及一些開發(fā)者的信息,而公鑰M是來自MAC系統(tǒng),在Mac系統(tǒng)中生成非對(duì)稱加密算法的一對(duì)公鑰\私鑰(你的Xcode幫你代辦了).這里稱為公鑰M ?私鑰M . M = Mac

拿到CSR文件后,到Apple developer官網(wǎng)申請(qǐng)證書,上面講過,iOS系統(tǒng)也有一對(duì)非對(duì)稱加密鑰匙,公鑰A在iOS系統(tǒng),私鑰A在apple后臺(tái),蘋果后臺(tái)拿到CSR文件后,會(huì)用私鑰A對(duì)CSR文件里面的公鑰M的hash值進(jìn)行簽名,然后跟上傳的其他信息,打包生成證書文件,開發(fā)者通過下載拿到該證書,就可以進(jìn)行代碼打包分發(fā),過程如下:

而打包過程就是編譯完app后,通過MAC系統(tǒng)的私鑰M對(duì)編譯后的代碼的Hash值進(jìn)行簽名,然后將證書、簽名的hash值、編譯的代碼一起打包進(jìn)行分發(fā),用戶拿到app包安裝到iOS系統(tǒng),iOS系統(tǒng),會(huì)先通過iOS的公鑰A對(duì)證書里面的公鑰M進(jìn)行驗(yàn)證,驗(yàn)證通過,然后拿公鑰M對(duì)代碼簽名進(jìn)行驗(yàn)證,過程如下:

但是,上述這個(gè)過程就完美了么?那豈不是,一證在手,天下我有?。?!已經(jīng)介紹了簡單的應(yīng)用簽名但是這種簽名方式并不能解決應(yīng)用濫用的問題,所以蘋果又加了兩個(gè)限制.第一限制在蘋果后臺(tái)注冊(cè)過的設(shè)備才可以安裝.第二限制簽名只能針對(duì)某一個(gè)具體的APP.并且蘋果還想控制App里面的iCloud/PUSH/后臺(tái)運(yùn)行/調(diào)試器附加這些權(quán)限,所以蘋果把這些權(quán)限開關(guān)統(tǒng)一稱為Entitlements(授權(quán)文件).并將這個(gè)文件放在了一個(gè)叫做Provisioning Profile(描述文件)文件中.描述文件是在AppleDevelop網(wǎng)站創(chuàng)建的(在Xcode中填上AppleID它會(huì)代辦創(chuàng)建),Xcode運(yùn)行時(shí)會(huì)打包進(jìn)入APP內(nèi).
所以我們使用CSR申請(qǐng)證書時(shí),我們還要申請(qǐng)一個(gè)東西!! 就是描述文件!!流程如下


當(dāng)然,Provisioning profile本身也是通過簽名認(rèn)證的,所以別想著你可以更改里面的東西來達(dá)到擴(kuò)充權(quán)限\設(shè)備的目的.只有老老實(shí)實(shí)的去網(wǎng)站向Apple申請(qǐng)一份權(quán)限更多\設(shè)備更多的profile。
整體的流程
首先我們總結(jié)一下剛才的一些名詞
證書:內(nèi)容是公鑰或者私鑰,由認(rèn)證機(jī)構(gòu)對(duì)其簽名組成的數(shù)據(jù)包!我們開發(fā)可以使用鑰匙串訪問看到
P12:就是本地私鑰,可以導(dǎo)入到其他電腦
Entitlements:權(quán)限文件,包含了APP一些權(quán)限的plist文件
CertificateSigningRequest:CSR文件包含了本地公鑰的數(shù)據(jù)文件
Provisioning Profile:描述文件,包含了證書/Entitlements等數(shù)據(jù),并由蘋果后臺(tái)私鑰簽名的數(shù)據(jù)包.
流程如下:
第 1 步對(duì)應(yīng)的是 keychain 里的 “從證書頒發(fā)機(jī)構(gòu)請(qǐng)求證書”,這里就本地生成了一對(duì)公私鑰,保存的 CertificateSigningRequest 里面就包含公鑰,私鑰保存在本地電腦里.
第 2 步向蘋果申請(qǐng)對(duì)應(yīng)把 CSR 傳到蘋果后臺(tái)生成證書.
第 3 步證書下載到本地.這時(shí)本地有兩個(gè)證書.一個(gè)是第 1 步生成的私鑰,一個(gè)是這里下載回來的證書,keychain 會(huì)把這兩個(gè)證書關(guān)聯(lián)起來,因?yàn)樗麄児借€是對(duì)應(yīng)的,在XCode選擇下載回來的證書時(shí),實(shí)際上會(huì)找到 keychain 里對(duì)應(yīng)的私鑰去簽名.這里私鑰只有生成它的這臺(tái) Mac 有,如果別的 Mac 也要編譯簽名這個(gè) App 怎么辦?答案是把私鑰導(dǎo)出給其他 Mac 用,在 keychain 里導(dǎo)出私鑰,就會(huì)存成 .p12 文件,其他 Mac 打開后就導(dǎo)入了這個(gè)私鑰.
第 4 步都是在蘋果網(wǎng)站上操作,配置 AppID / 權(quán)限 / 設(shè)備等,最后下載 Provisioning Profile 文件。
第 5 步 XCode 會(huì)通過第 3 步下載回來的證書(存著公鑰),在本地找到對(duì)應(yīng)的私鑰(第一步生成的),用本地私鑰去簽名 App,并把 Provisioning Profile 文件命名為 embedded.mobileprovision 一起打包進(jìn)去。所以任何本地調(diào)試的APP,都會(huì)有一個(gè)embedded.mobileprovision(描述文件)從App Store下載的沒有.
以上就是iOS的數(shù)字證書簽名,歡迎指正。
參考:iOS應(yīng)用簽名(下)
? ? ? ? ? ? iOS應(yīng)用簽名(上)