前言
本篇文章雖然是介紹iOS開(kāi)發(fā)中ipa包的簽名原理。但因?yàn)楹灻婕暗矫艽a學(xué)中的概念霜浴。在了解簽名之前,我們需要明確一些概念蓝纲。密碼學(xué)中阴孟,根據(jù)加解密密鑰的不同,通常把加密方式分為對(duì)稱密碼(對(duì)稱加密)和公鑰密碼(非對(duì)稱加密)驻龟。常見(jiàn)加密算法有:DES温眉、3DES、DESX翁狐、AES类溢、RSA、ECC露懒。其中RSA闯冷、ECC是非對(duì)稱加密算法。以下是一些必要的概念懈词。
對(duì)稱密碼:又叫做對(duì)稱加密蛇耀。加密和解密使用的是同一個(gè)密鑰。
公鑰密碼:又叫做非對(duì)稱加密坎弯。有一個(gè)公鑰和一個(gè)私鑰纺涤,公鑰和私鑰組成一個(gè)密鑰對(duì)。使用私鑰加密的數(shù)據(jù)可以使用公鑰解密抠忘,反之亦然撩炊。
混合加密:同時(shí)使用對(duì)稱加密和非對(duì)稱加密兩類算法。
消息摘要:通過(guò)單向散列函數(shù)對(duì)消息進(jìn)行一定的運(yùn)算崎脉,計(jì)算出固定長(zhǎng)度的結(jié)果拧咳,就是消息摘要。
數(shù)字簽名:用私鑰對(duì)消息摘要(又叫哈希值囚灼、散列值)進(jìn)行加密得到的密文就是數(shù)字簽名
數(shù)字證書(shū):按照一定格式將明文信息和消息摘要進(jìn)行打包得到的文件就是證書(shū)骆膝。
中間人攻擊: 中間人通過(guò)在網(wǎng)絡(luò)中攔截并持有端到端的真實(shí)公鑰,然后把自己的公鑰轉(zhuǎn)發(fā)給消息接收者灶体。而后通過(guò)公鑰攔截解析消息甚至篡改的一種攻擊方式阅签。
加密
對(duì)稱密碼
又叫做對(duì)稱加密,一種加密和解密使用同一個(gè)密鑰的加密算法赃春。 即在對(duì)稱密碼中愉择,密鑰既可以對(duì)數(shù)據(jù)進(jìn)行加密,又可以對(duì)數(shù)據(jù)進(jìn)行解密。
特點(diǎn)
對(duì)稱加密的優(yōu)點(diǎn)是加解密速度快锥涕。缺點(diǎn)是對(duì)稱加密的算法的密鑰在傳輸過(guò)程中和保存的安全性問(wèn)題衷戈。因?yàn)榧咏饷苁褂猛粋€(gè)密鑰,一旦密鑰被泄露层坠,數(shù)據(jù)的隱私性和完整性將受到很大的威脅殖妇。
算法
對(duì)稱加密的常見(jiàn)算法有DES、3DES破花、DESX谦趣、AES。
公鑰密碼
公鑰密碼即我們常說(shuō)的非對(duì)稱加密座每,也稱為公私鑰加密前鹅。此類算法有一個(gè)公鑰和一個(gè)私鑰。公鑰和私鑰一一對(duì)應(yīng)峭梳,共同組成一個(gè)密鑰對(duì)舰绘,每個(gè)密鑰對(duì)中的公鑰和私鑰是不同的。密鑰對(duì)由網(wǎng)絡(luò)中的通訊設(shè)備生成葱椭,通常是客戶端或服務(wù)器捂寿。此處我們以PC客戶端為例,PC客戶端生成密鑰對(duì)后孵运,自己持有私鑰秦陋,然后將公鑰通過(guò)網(wǎng)絡(luò)分發(fā)給其他PC客戶端。公鑰加密的數(shù)據(jù)需要私鑰解密治笨,反之亦然驳概。公鑰是公開(kāi)的,可公開(kāi)分發(fā)給其他PC客戶端旷赖,但私鑰只有密鑰對(duì)生成者持有且不能泄露抡句,一旦私鑰泄露將會(huì)危及數(shù)據(jù)的安全。
特點(diǎn)
非對(duì)稱加密的缺點(diǎn)是加解密速度要遠(yuǎn)遠(yuǎn)慢于對(duì)稱加密杠愧,在某些極端情況下,甚至能比非對(duì)稱加密慢上1000倍逞壁。
公鑰可公開(kāi)流济,私鑰需保密。
算法
常見(jiàn)的非對(duì)稱加密算法有RSA腌闯、Diffie-Hellman绳瘟、ECC(移動(dòng)設(shè)備使用)
密鑰配送問(wèn)題
上述我們簡(jiǎn)單了解了對(duì)稱加密和非對(duì)稱加密的概念和特點(diǎn)。對(duì)稱加密中加解密使用的是同一個(gè)密鑰姿骏,密鑰在網(wǎng)絡(luò)的配送過(guò)程一旦被非法竊取糖声,數(shù)據(jù)的私密性和完整性無(wú)法得到保證。所以采用對(duì)稱加密需要解決密鑰的配送問(wèn)題。常見(jiàn)的解決方案有:
●? 通過(guò)事先共享密鑰來(lái)解決
●? 通過(guò)密鑰分配中心來(lái)解決
●? 通過(guò) Diffie-Hellman 密鑰交換來(lái)解決
●? 通過(guò)公鑰密碼來(lái)解決
通過(guò)對(duì)稱加密的特點(diǎn)蘸泻,我們了解了對(duì)稱加密的加解密速度快琉苇,但是存在密鑰配送問(wèn)題。非對(duì)稱加密不存在密鑰配送問(wèn)題悦施,但是加解密速度慢并扇。結(jié)合這兩類加密方式的特點(diǎn),前輩們發(fā)明了對(duì)稱加密+非對(duì)稱加密的混合加密方式抡诞,即對(duì)稱加密+非對(duì)稱加密雙重混合加密穷蛹,稱為混合密碼系統(tǒng)≈绾梗混合密碼系統(tǒng)是將對(duì)稱加密和非對(duì)稱加密的優(yōu)勢(shì)相結(jié)合的方法肴熏。讓我們來(lái)看看是如何實(shí)現(xiàn)的:
會(huì)話密鑰:本質(zhì)上就是隨機(jī)生成的對(duì)稱密鑰。消息發(fā)送方和接收方每次會(huì)話都會(huì)通過(guò)偽隨機(jī)數(shù)生成器生成一個(gè)對(duì)稱密鑰顷窒,每次生成的對(duì)稱密鑰可能都不相同蛙吏,這種想對(duì)稱密鑰稱為會(huì)話密鑰。
加密步驟:
消息接收方:生成非對(duì)稱密鑰對(duì)蹋肮,把公鑰發(fā)送給消息發(fā)送方
消息發(fā)送方:生成隨機(jī)的會(huì)話密鑰出刷,本質(zhì)就是對(duì)稱密鑰
消息發(fā)送方:使用對(duì)稱密鑰對(duì)消息進(jìn)行加密
消息發(fā)送方:使用公鑰對(duì)會(huì)話密鑰進(jìn)行加密從而生成會(huì)話密鑰的密文
消息發(fā)送方:把用會(huì)話密鑰的密文和用會(huì)話密鑰加密過(guò)的消息一并發(fā)給消息接收方
解密步驟:
消息接收方:使用自己的私鑰對(duì)加密過(guò)的會(huì)話密鑰進(jìn)行解密獲得明文的會(huì)話密鑰
然后用明文的會(huì)話密鑰對(duì)消息進(jìn)行解密獲得明文消息
使用混合密碼系統(tǒng)解決了密鑰配送問(wèn)題:因?yàn)閷?duì)稱密鑰在網(wǎng)絡(luò)上配送的是密文,密文是對(duì)稱密鑰使用公鑰加密后的結(jié)果坯辩,只能通過(guò)私鑰進(jìn)行解密馁龟,即便密文的對(duì)稱密鑰被第三方非法竊取,但因?yàn)榈谌經(jīng)]有對(duì)應(yīng)的私鑰漆魔,無(wú)法對(duì)密文的對(duì)稱密鑰進(jìn)行解密坷檩,也就能夠保證對(duì)稱密鑰的安全性。
為什么不是使用公鑰對(duì)消息進(jìn)行加密改抡,再使用會(huì)話密鑰對(duì)公鑰進(jìn)行加密呢矢炼?
1.公鑰本身就是公開(kāi)的,不需要對(duì)公鑰進(jìn)行加密阿纤,對(duì)公鑰加密無(wú)意義句灌,上圖中公鑰用于加密數(shù)據(jù),即便竊聽(tīng)者獲取了明文的公鑰也只能對(duì)數(shù)據(jù)加密欠拾,而沒(méi)有私鑰無(wú)法對(duì)數(shù)據(jù)解密 胰锌。
2.使用公鑰對(duì)數(shù)據(jù)加密沒(méi)有解決非對(duì)稱加密方式頻繁加密大量數(shù)據(jù)的低效問(wèn)題。
小結(jié)
因?yàn)閷?duì)稱加密算法的加解密速度比非對(duì)稱加密算法的快藐窄,在日常的網(wǎng)絡(luò)數(shù)據(jù)傳輸中资昧,經(jīng)常會(huì)頻繁的傳輸大量的網(wǎng)絡(luò)數(shù)據(jù),使用非對(duì)稱加密這種安全但不高效的加密方式進(jìn)行加密顯然是不可取的荆忍,所以應(yīng)該采用對(duì)稱密鑰加密消息格带。但對(duì)稱密鑰需要在網(wǎng)絡(luò)上進(jìn)行傳輸撤缴,且極易容易被破解。所以需要保證對(duì)稱密鑰在網(wǎng)絡(luò)傳輸中的安全性叽唱,即需要保證對(duì)稱密鑰在網(wǎng)絡(luò)配送過(guò)程中的安全性屈呕。所以最終的方案是使用對(duì)稱密鑰對(duì)消息進(jìn)行加解密,再使用非對(duì)稱加密的公鑰對(duì)對(duì)稱密鑰進(jìn)行加密尔觉,最后在網(wǎng)絡(luò)上配送的是被公鑰加密過(guò)的對(duì)稱密鑰和對(duì)稱密鑰加密過(guò)的消息(因?yàn)閷?duì)稱密鑰數(shù)據(jù)長(zhǎng)度比較短凉袱,使用非對(duì)稱加密方式加密并不會(huì)很低效)。這種方式被稱為混合加密(混合密碼) 即用非對(duì)稱加密(通常是RSA)解決密鑰配送問(wèn)題侦铜,用對(duì)稱加密(AES)解決加密效率問(wèn)題专甩。
HTTPS中的SSL就是使用的混合密碼系統(tǒng)。
消息摘要
除對(duì)稱加密和非對(duì)稱加密之外钉稍,還有一種特殊的加密方式——消息摘要涤躲。消息摘要又叫做Hash算法、單向散列算法贡未。準(zhǔn)確的說(shuō)种樱,消息摘要不算是一種加密方式,因?yàn)橄⒄遣豢赡娴那蚁⒄拈L(zhǎng)度和消息的長(zhǎng)度無(wú)關(guān)俊卤,所以就沒(méi)有和對(duì)稱加密嫩挤、非對(duì)稱加密混為一談。
消息摘要函數(shù)(message digest function)
消息摘要函數(shù)又被稱為哈希函數(shù)(hash function)消恍。單向散列函數(shù)(One-way hash function)
哈希函數(shù)可以根據(jù)消息內(nèi)容計(jì)算出對(duì)應(yīng)的哈希值岂昭。哈希值的長(zhǎng)度和消息的長(zhǎng)度無(wú)關(guān),無(wú)論消息是1bit狠怨、10M约啊、100G,哈希函數(shù)都會(huì)計(jì)算出固定長(zhǎng)度的哈希值佣赖。輸出的哈希值也被稱為消息摘要(message digest)恰矩、指紋(fingerprint)、散列值憎蛤。
特點(diǎn)
消息摘要長(zhǎng)度固定外傅。無(wú)論明文消息長(zhǎng)度是多少个唧,使用同一個(gè)消息摘要函數(shù)計(jì)算出的消息摘要的長(zhǎng)度是固定的岛心。
消息摘要函數(shù)計(jì)算速度快。相比較其他復(fù)雜的計(jì)算方式窃诉,消息摘要函數(shù)計(jì)算速度快豆胸。
消息明文和摘要一一對(duì)應(yīng)。同樣的消息經(jīng)過(guò)同一個(gè)摘要函數(shù)計(jì)算的散列值永遠(yuǎn)相同巷疼,不同的消息計(jì)算的散列值也不同晚胡。
消息摘要具備不可逆性灵奖。消息摘要函數(shù)又叫做單向散列函數(shù),顧名思義估盘,函數(shù)具備單向性和不可逆性瓷患。正常情況下,無(wú)法通過(guò)算法計(jì)算消息摘要對(duì)應(yīng)的明文消息遣妥。
算法
單向散列算法是一個(gè)概念和標(biāo)準(zhǔn)擅编,而不是一個(gè)具體的算法。常見(jiàn)的單向散列算法有:MD2箫踩、MD4爱态、MD5、HAVAL境钟、SHA锦担、SHA-1、HMAC慨削、HMAC-MD5洞渔、HMAC-SHA1、SHA-256缚态。目前最常用的且相對(duì)安全的是SHA-256磁椒,SHA-256的散列值長(zhǎng)度就是256bit。此外還有SHA-384玫芦、SHA-512浆熔。SHA-3是正在研究的全新標(biāo)準(zhǔn)。
macOS上自帶md5散列函數(shù):
消息摘要的應(yīng)用
因?yàn)橄⒄兔魑牡囊灰粚?duì)應(yīng)關(guān)系以及不可逆性姨俩,所以消息摘要通常用來(lái)驗(yàn)證消息的完整性和真實(shí)性蘸拔,以及用于不可還原的密碼存儲(chǔ)。
1.防止數(shù)據(jù)篡改
- 單向散列函數(shù)的應(yīng)用場(chǎng)景之一就是防止(驗(yàn)證)數(shù)據(jù)是否被篡改环葵,一旦發(fā)現(xiàn)數(shù)據(jù)被篡改則丟棄該數(shù)據(jù)调窍。所以需要事先保證散列值的安全性,即不能把散列值暴露出去张遭,也不能在網(wǎng)絡(luò)上傳輸散列值邓萨。
- 一些軟件網(wǎng)站為了保證用戶從任何渠道下載的軟件是正版未被篡改的,通常會(huì)在自己的官網(wǎng)上掛出軟件的散列值菊卷。使用者從其他渠道下載了軟件之后對(duì)軟件進(jìn)行散列值計(jì)算缔恳,和官網(wǎng)的散列值對(duì)比即可驗(yàn)證下載的軟件是否為正版可信賴。
2.密碼口令加密
- 單向散列函數(shù)的另一個(gè)應(yīng)用場(chǎng)景就是用戶的登錄口令加密洁闰。為了保證用戶敏感信息的私密性歉甚,互聯(lián)網(wǎng)上傳輸?shù)氖请[私數(shù)據(jù)通常是經(jīng)過(guò)散列函數(shù)計(jì)算過(guò)的散列值,數(shù)據(jù)庫(kù)里存儲(chǔ)的也可以是散列值而非明文扑眉。這樣用戶的明文密碼無(wú)論是在傳輸過(guò)程中還是在存儲(chǔ)過(guò)車中都不會(huì)被泄露纸泄。
數(shù)字簽名
有了上述的對(duì)稱密碼赖钞、公鑰密碼、單向散列函數(shù)是不是就可以滿足我們的數(shù)據(jù)安全需求了呢聘裁?答案是否定的雪营。
對(duì)稱密碼和公鑰密碼僅解決了數(shù)據(jù)的加密問(wèn)題,但依然無(wú)法徹底避免數(shù)據(jù)篡改和身份偽裝衡便。比如 常見(jiàn)的中間人攻擊献起,就是在網(wǎng)絡(luò)中攔截公鑰并轉(zhuǎn)發(fā)自己的公鑰來(lái)實(shí)現(xiàn)消息攔截和篡改的。我們常見(jiàn)的網(wǎng)絡(luò)代理應(yīng)用——Charles就是采用中間人攻擊的方式實(shí)現(xiàn)網(wǎng)絡(luò)代理镣陕。
因?yàn)閷?duì)稱密碼谴餐、公鑰密碼、單向散列函數(shù)都無(wú)法同時(shí)滿足【防篡改茁彭、防偽裝总寒、防否認(rèn)】。所以需要一種新的技術(shù)來(lái)識(shí)別數(shù)據(jù)篡改理肺、偽裝摄闸、否認(rèn)。這種技術(shù)就是數(shù)字簽名妹萨。
作用
數(shù)字簽名通過(guò)一系列手段可以識(shí)別數(shù)據(jù)是否被篡改年枕、識(shí)別消息發(fā)送方的真實(shí)身份是否合法,防止消息發(fā)送方否認(rèn)乎完。所以熏兄,數(shù)字簽名的作用就是防止篡改、偽裝树姨、否認(rèn)摩桶。
數(shù)字簽名加密
數(shù)字簽名加密即指對(duì)消息執(zhí)行數(shù)字簽名的處理過(guò)程,如下:
- 將明文消息進(jìn)行摘要處理(以MD5為例)帽揪,得到對(duì)應(yīng)的消息摘要
- 用私鑰對(duì)消息摘要進(jìn)行加密得到摘要的密文硝清,密文稱之為數(shù)字簽名
數(shù)字簽名解密
數(shù)字簽名解密即指對(duì)消息摘要執(zhí)行解密和驗(yàn)證的處理過(guò)程,如下:
- 使用公鑰解密數(shù)字簽名(私鑰加密的摘要)得到解密后的消息摘要A
- 使用相同算法的單向散列函數(shù)對(duì)明文消息進(jìn)行摘要計(jì)算得到消息摘要B
- 對(duì)比消息摘要A和消息摘要B是否相等转晰,即可驗(yàn)證數(shù)據(jù)的完整性和真實(shí)性
數(shù)字簽名特點(diǎn):
- 用私鑰加密摘要芦拿,用公鑰驗(yàn)證摘要
- 明文消息和數(shù)字簽名都會(huì)發(fā)送給接收者
- 無(wú)法保證消息的機(jī)密性,只能保證消息摘要的機(jī)密性
- 數(shù)字簽名得到的結(jié)果是消息摘要的密文查邢,不是消息的密文
- 數(shù)字簽名是一個(gè)【消息摘要+私鑰加密】的過(guò)程蔗崎,相對(duì)于單純的消息摘要多了一步私鑰加密。
數(shù)字簽名的完整過(guò)程
- 發(fā)送者生成密鑰對(duì)
- 發(fā)送者把公鑰發(fā)送給消息接收者
- 發(fā)送者把消息生成消息摘要
- 發(fā)送者用私鑰加密消息摘要
- 發(fā)送者將明文消息和加密后的消息摘要發(fā)送給消息接收者
- 接收者對(duì)明文消息生成摘要A
- 接收者用公鑰解密密文摘要扰藕,得到明文消息摘要B
- 接收者對(duì)比第5缓苛、6步的消息摘要A、B邓深,相等則說(shuō)明消息未被篡改
為什么要對(duì)數(shù)據(jù)的哈希值進(jìn)行加密而不是對(duì)數(shù)據(jù)本身進(jìn)行加密他嫡?
通常網(wǎng)絡(luò)數(shù)據(jù)較長(zhǎng)番官,直接用私鑰對(duì)數(shù)據(jù)進(jìn)行加密后的密文可能會(huì)很長(zhǎng)。
數(shù)據(jù)的哈希值通常是固定長(zhǎng)度的钢属,且長(zhǎng)度不會(huì)很長(zhǎng),所以對(duì)哈希值進(jìn)行加密后的密文不會(huì)很長(zhǎng)门躯,方便網(wǎng)絡(luò)傳輸淆党。
數(shù)字簽名的目的
數(shù)字簽名發(fā)送的是【明文消息+數(shù)字簽名】。即數(shù)據(jù)在網(wǎng)絡(luò)上是明文傳輸?shù)难攘梗詿o(wú)法保證數(shù)據(jù)的機(jī)密性染乌。并且這也不是數(shù)字簽名的目的。
數(shù)字簽名的目的是識(shí)別接收的數(shù)據(jù)的真實(shí)性和完整性(即有沒(méi)有被篡改數(shù)據(jù)(對(duì)比消息摘要)懂讯、有沒(méi)有被偽裝身份(公鑰解密簽名)荷憋、保證發(fā)送者無(wú)法否認(rèn)(和身份偽裝是一回事,因?yàn)槭怯冒l(fā)送者的私鑰加密的消息摘要褐望,所以發(fā)送者不能否認(rèn)))勒庄。
中間人攻擊
因?yàn)楣€是需要在網(wǎng)絡(luò)上傳輸?shù)模怨€有可能被中間人攔截篡改瘫里,這種篡改公鑰的攻擊方式叫中間人攻擊实蔽。Charles代理的方式就是中間人攻擊的應(yīng)用。
中間人攻擊是通過(guò)攔截并持有真正的公鑰谨读,轉(zhuǎn)發(fā)自己的公鑰來(lái)實(shí)現(xiàn)消息的篡改和轉(zhuǎn)發(fā)局装。一旦公鑰被攔截篡改,消息接收者收到的將是中間人的公鑰劳殖,那么數(shù)字簽名將形同虛設(shè)铐尚。
綜上,問(wèn)題就演變成:
要正確使用簽名哆姻,前提是需要保證:用于驗(yàn)證簽名的公鑰必須屬于真正的發(fā)送者宣增。
所以如何保 證公鑰屬于真正的消息發(fā)送者?
為了保證驗(yàn)證簽名的公鑰屬于真正的消息發(fā)送者填具,即避免遭受中間人攻擊攔截&偽造公鑰统舀,即保證數(shù)字簽名的公鑰的真實(shí)性合法性,需要CA證書(shū)
公鑰證書(shū)
上面通過(guò)介紹數(shù)字簽名劳景,了解到簽名的原理是消息發(fā)送端用私鑰加密消息摘要誉简,消息接收端用公鑰解密消息摘要。又了解到中間人攻擊可以攔截公鑰并轉(zhuǎn)發(fā)自己的公鑰盟广,所以要正確使用簽名闷串,前提是需要保證:用于驗(yàn)證簽名的公鑰必須屬于真正的發(fā)送者。如何保證數(shù)字簽名的公鑰是真實(shí)的呢筋量?這里就用到了公鑰證書(shū)(Public-key Certificate烹吵,PKC)碉熄。
什么是公鑰證書(shū)?
要開(kāi)車先得考駕照肋拔,駕照上面記有本人的照片锈津、姓名、出生日期等個(gè)人信息凉蜂,以及有效期琼梆、準(zhǔn)駕車輛的類型等信息。并由公安局在上面蓋章窿吩。我們只要看到駕照茎杂,就可以知道公安局認(rèn)定此人具有駕駛車輛的資格。
公鑰證書(shū)其實(shí)和駕照很相似纫雁,里面記有姓名煌往、組織、郵箱地址等個(gè)人信息轧邪,以及屬于此人的公鑰刽脖,并由認(rèn)證機(jī)構(gòu)(Certification Authority、Certifying Authority闲勺,CA)施加數(shù)字簽名曾棕。只要看到公鑰證書(shū),我們就可以知道認(rèn)證機(jī)構(gòu)認(rèn)定該公鑰的確屬于此人菜循。公鑰證書(shū)也簡(jiǎn)稱證書(shū)翘地。
以上是筆者摘自《圖解密碼技術(shù)》一書(shū)中對(duì)公鑰證書(shū)的定義。
作用
通過(guò)公鑰證書(shū)的定義癌幕,可見(jiàn)公鑰證書(shū)本質(zhì)上就是對(duì)公鑰的簽名認(rèn)證衙耕,已達(dá)到認(rèn)證公鑰確實(shí)屬于某個(gè)機(jī)構(gòu)、組織或個(gè)人的目的勺远。
所以公鑰證書(shū)的作用是驗(yàn)證公鑰的真實(shí)性橙喘。這樣就可以解決公鑰配送過(guò)程中被中間人攻擊的問(wèn)題。
證書(shū)結(jié)構(gòu)
- 里面有名稱胶逢、郵箱等個(gè)人或機(jī)構(gòu)信息厅瞎,以及個(gè)人或機(jī)構(gòu)的公鑰
- 包含認(rèn)證機(jī)構(gòu)(Certificate Authority,CA)施加的數(shù)字簽名
- 所以證書(shū)包括兩類元素:公鑰信息+公鑰信息的簽名
何為CA(Certificate Authority)
CA就是我們上面說(shuō)的認(rèn)證機(jī)構(gòu)
- CA就是能夠認(rèn)定“公鑰確實(shí)屬于此人”并能夠生成數(shù)字簽名的個(gè)人或者組織
- 有國(guó)際性組織初坠、政府設(shè)立的組織和簸。有通過(guò)提供認(rèn)證服務(wù)來(lái)盈利的企業(yè)
- 個(gè)人也可以成立認(rèn)證機(jī)構(gòu)
注冊(cè)和使用證書(shū)
注冊(cè)證書(shū)
1.消息接收者生成密鑰對(duì)
2.消息接收者將密鑰對(duì)的公鑰發(fā)送給CA機(jī)構(gòu)
3.CA機(jī)構(gòu)用CA自己的私鑰對(duì)消息接收者的公鑰施加數(shù)字簽名
4.CA機(jī)構(gòu)通過(guò)上一步生成的數(shù)字簽名和消息接收者的公鑰生成公鑰證書(shū)
使用證書(shū)
1.消息發(fā)送者從CA機(jī)構(gòu)獲取到指定的公鑰證書(shū)
2.消息發(fā)送者通過(guò)預(yù)置的CA機(jī)構(gòu)的公鑰驗(yàn)證公鑰證書(shū)的合法性
- 使用哈希函數(shù)對(duì)公鑰證書(shū)中的公鑰進(jìn)行單向散列求得散列值A(chǔ)
- 使用預(yù)置的CA機(jī)構(gòu)的公鑰解密公鑰證書(shū)的數(shù)字簽名獲得散列值B
- 對(duì)比散列值A(chǔ)和散列值B是否相等,相等則說(shuō)明公鑰合法碟刺,否則不合法
3.消息發(fā)送者使用證書(shū)中的公鑰對(duì)傳輸?shù)臅?huì)話密鑰(對(duì)稱密鑰)進(jìn)行加密(采用混合密碼系統(tǒng))
HTTPS中的證書(shū)就是指CA證書(shū)
iOS簽名機(jī)制
一些概念
在了解iOS簽名機(jī)制之前锁保,我們必須先對(duì)齊一些概念,以及每個(gè)概念背后的意義。這些概念主要包括:
- .certSigningRequest
- .cer
- .mobileprovision
- Entitlements
- p12
Mac公鑰證書(shū)(.certSigningRequest)*
.certSigningRequest文件是以certSigningRequest作為后綴名的文件爽柒,也就是我們常說(shuō)的CSR文件吴菠。CSR文件是從macOS的鑰匙串的證書(shū)助理中通過(guò)證書(shū)頒發(fā)機(jī)構(gòu)請(qǐng)求的公鑰證書(shū)*。Mac作為證書(shū)頒發(fā)機(jī)構(gòu)浩村,生成的密鑰對(duì)默認(rèn)采用RSA算法做葵,密鑰大小默認(rèn)2048位。
Apple證書(shū)(.cer)
- 利用Apple私鑰(CA)對(duì)Mac的公鑰(CSR)進(jìn)行簽名后獲得的公鑰證書(shū)
- .cer證書(shū)主要包括兩個(gè)元素:明文的Mac公鑰心墅、Mac公鑰的簽名(用Apple私鑰對(duì)Mac公鑰簽名)
描述文件(.mobileprovision)
- 利用Apple私鑰對(duì)【Apple證書(shū)+iOS devices+appId+app權(quán)限文件entitlements】進(jìn)行簽名
- 描述文件包括【Apple證書(shū)+iOS devices+appId+app權(quán)限文件entitlements】以及以上信息的數(shù)字簽名
所以蜂挪,描述文件最終描述(限制)了:證書(shū)、iOS devices嗓化、appId、app的權(quán)限谬哀。
描述文件是開(kāi)發(fā)期使用的文件刺覆,App Store下載的App不存在描述文件。
權(quán)限列表(Entitlements)
權(quán)限列表包含了 App 擁有的所有權(quán)限史煎,比如消息push權(quán)限谦屑、后臺(tái)運(yùn)行權(quán)限。
p12
p12本質(zhì)是Mac本地私鑰的另一種形式篇梭,可以在鑰匙串訪問(wèn)(Keychain Access)中導(dǎo)出p12文件給其他Mac設(shè)備氢橙,其他Mac設(shè)備把p12安裝到自己的鑰匙串中后就可以進(jìn)行身份偽裝。
傳統(tǒng)真機(jī)調(diào)試
在Xcode6之前恬偷,不管是真機(jī)調(diào)試悍手,還是發(fā)布APP,開(kāi)發(fā)者都需要按年購(gòu)買一個(gè)付費(fèi)的Apple ID袍患,在開(kāi)發(fā)一個(gè)新的App時(shí)坦康,需要去Apple后臺(tái)執(zhí)行一系列復(fù)雜的配置步驟,目的就是要生成一個(gè)iOS開(kāi)發(fā)證書(shū)和一個(gè)對(duì)App的描述文件诡延,操作步驟如下:
- Mac上生成CSR文件(默認(rèn)名為CertificateSigningRequest.certSigningRequest)
- 使用付費(fèi)的開(kāi)發(fā)者賬號(hào)(Apple ID)登錄Apple開(kāi)發(fā)者后臺(tái)
- Apple 后臺(tái)上傳CertificateSigningRequest.certSigningRequest文件
- 下載Apple證書(shū)滞欠,可能是ios_development.cer(開(kāi)發(fā)證書(shū))或 ios_distribution.cer(發(fā)布證書(shū))
- 獲取iOS設(shè)備的UDID,Apple后臺(tái)通過(guò)UDID注冊(cè)Devices
- Apple后臺(tái)添加一個(gè)App ID
- 通過(guò)勾選Apple證書(shū)肆良、Devices筛璧、App ID、entitlements配置一個(gè)*.mobileprovision文件
- 下載*.mobileprovision文件
- 安裝Apple證書(shū)和*.mobileprovision文件
模擬器調(diào)試則不需要執(zhí)行以上配置惹恃,也不需要在Xcode添加Apple ID夭谤。對(duì)于真機(jī)調(diào)試,現(xiàn)在的Xcode會(huì)自動(dòng)幫開(kāi)發(fā)者執(zhí)行以上操作座舍。所以沮翔,非必要情況下,大多數(shù)開(kāi)發(fā)場(chǎng)景是不涉及到以上繁瑣的配置的。
App分發(fā)方式
Apple根據(jù)iOS App安裝渠道來(lái)源的不同采蚀,對(duì)App的簽名方式有所區(qū)別疲牵。通常App的安裝渠道可以分為:
- App Store。應(yīng)用市場(chǎng)分發(fā)榆鼠。對(duì)Apple用戶分發(fā)的線上正式的App纲爸。不限制用戶數(shù)量。
- In-House妆够。企業(yè)內(nèi)部分發(fā)识啦。可以直接安裝企業(yè)證書(shū)簽名后的App神妹。不限制用戶數(shù)量颓哮。
- AD-Hoc。企業(yè)內(nèi)部分發(fā)的限制版鸵荠。限制App安裝設(shè)備的數(shù)量冕茅,通常用于內(nèi)部小范圍使用或測(cè)試,使用場(chǎng)景有限蛹找。
- Xcode姨伤。開(kāi)發(fā)者分發(fā)。通過(guò)Xcode編譯App源代碼庸疾,將編譯成功的App安裝到手機(jī)上乍楚。
App Store分發(fā)
App Store簽名是最簡(jiǎn)單的簽名方式。只需要保證用戶安裝的App來(lái)源是App Store且被Apple認(rèn)可的届慈。
要實(shí)現(xiàn)這個(gè)需求很簡(jiǎn)單徒溪,最直接的方式,蘋(píng)果官方生成一對(duì)公私鑰拧篮,在 iOS 系統(tǒng)里內(nèi)置一個(gè)Apple公鑰词渤,私鑰由蘋(píng)果后臺(tái)保存,我們傳 ipa 到 AppStore 時(shí)串绩,蘋(píng)果后臺(tái)用私鑰對(duì) App 數(shù)據(jù)進(jìn)行簽名缺虐,iOS 系統(tǒng)下載這個(gè) App 后,用預(yù)置的Apple公鑰驗(yàn)證這個(gè)簽名礁凡,若簽名正確高氮,說(shuō)明這個(gè) App 肯定是由蘋(píng)果后臺(tái)認(rèn)證的,并且下載和安裝過(guò)程中都沒(méi)有修改過(guò)App顷牌,也就達(dá)到了蘋(píng)果的需求:保證安裝的每一個(gè) APP 都是經(jīng)過(guò)蘋(píng)果官方允許的剪芍。事實(shí)上,Apple也是這么做的窟蓝。Apple會(huì)對(duì)我們提審App Store的App進(jìn)行重簽名罪裹,所謂重簽名就是對(duì)開(kāi)發(fā)者提審的ipa包中的App進(jìn)行重簽,重簽發(fā)生在Apple的后臺(tái),使用的Apple自己的私鑰状共。具體重簽流程后面介紹套耕,這里僅作為了解。
線下分發(fā)
上面App Store對(duì)應(yīng)用市場(chǎng)分發(fā)的App進(jìn)行簽名峡继,很好的保證了App的安全性冯袍。但我們知道,除了App Store分發(fā)的應(yīng)用外碾牌,還有其他三種應(yīng)用分發(fā)方式:In-House康愤、AD-Hoc、Xcode舶吗。這三種方式生成的App文件不會(huì)上傳到App Store征冷,但Apple還是要兼顧這些法外之地的App的合規(guī)性和安全性,對(duì)這些App的安裝和使用享有絕對(duì)的控制權(quán)誓琼。所以Apple還需要添加其他手段來(lái)驗(yàn)證這些非App Store分發(fā)的App资盅。這里就引出了上面所說(shuō)的描述文件——mobileprovision profile。
描述文件其實(shí)是Apple對(duì)App二次簽名的產(chǎn)物踊赠。蘋(píng)果想要對(duì)線下安裝的App享有控制權(quán),包括:
- 經(jīng)過(guò)蘋(píng)果允許才可以安裝使用App每庆。
- 指定的設(shè)備才能安裝使用線下分發(fā)的App筐带。
- 指定設(shè)備只能安裝指定的App,設(shè)備不能安裝非開(kāi)發(fā)期的App缤灵。
如上伦籍,第一條,蘋(píng)果想要控制經(jīng)過(guò)許可才可以線下安裝App腮出。通過(guò)我們對(duì)簽名和證書(shū)的認(rèn)識(shí)帖鸦,這個(gè)實(shí)現(xiàn)很簡(jiǎn)單。其步驟大致如下:
- Mac設(shè)備生成一對(duì)公私鑰胚嘲。Mac私鑰僅Mac本地持有作儿,開(kāi)發(fā)者將Mac公鑰上傳到Apple后臺(tái)。
- Apple后臺(tái)用Apple的私鑰對(duì)開(kāi)發(fā)者上傳的Mac公鑰進(jìn)行簽名馋劈,并生成一個(gè)Apple證書(shū)攻锰。
- 開(kāi)發(fā)者從Apple后臺(tái)下載Apple證書(shū),并將Apple證書(shū)安裝到Mac本地妓雾。
- 在Xcode編譯App或?qū)pp重簽名時(shí)娶吞,用Mac本地的私鑰對(duì)這個(gè)App進(jìn)行簽名,同時(shí)把第三步得到的Apple證書(shū)一起打包進(jìn)App 中械姻,然后安裝到手機(jī)上妒蛇。
- 在手機(jī)安裝App時(shí),iOS 系統(tǒng)從App中讀取出第三步的Apple證書(shū),然后通過(guò)系統(tǒng)內(nèi)置的Apple公鑰绣夺,去驗(yàn)證Apple證書(shū)的數(shù)字簽名的正確性吏奸。
- 驗(yàn)證證書(shū)后確保了Mac公鑰是蘋(píng)果認(rèn)證過(guò)的,再用Mac公鑰去驗(yàn)證 App的簽名(因?yàn)锳pp是使用Mac私鑰簽名的乐导,所以可以使用Mac公鑰驗(yàn)證簽名)苦丁,如果Mac公鑰驗(yàn)證App的簽名是正確的,就說(shuō)明App沒(méi)有被篡改過(guò)物臂,這里就間接驗(yàn)證了這個(gè) App 安裝行為是否經(jīng)過(guò)蘋(píng)果官方允許旺拉。(這里只驗(yàn)證安裝行為,不驗(yàn)證App 是否被改動(dòng)棵磷,因?yàn)殚_(kāi)發(fā)階段 App 內(nèi)容總是不斷變化的蛾狗,蘋(píng)果不需要管。)
簡(jiǎn)化的流程圖大致如下:
上述流程只解決了上面第一個(gè)需求仪媒,也就是經(jīng)過(guò)蘋(píng)果允許才可以安裝使用App沉桌,還未解決第2、3個(gè)問(wèn)題(2.指定的設(shè)備才能安裝使用線下分發(fā)的App 3.指定設(shè)備只能安裝指定的App算吩,設(shè)備不能安裝非開(kāi)發(fā)期的App)留凭。怎么解決呢?蘋(píng)果再加了兩個(gè)限制偎巢,一是限制在Apple后臺(tái)注冊(cè)過(guò)的設(shè)備才可以安裝App蔼夜,二是限制簽名只能針對(duì)某一個(gè)具體的 App(也就是Bundle ID)。
怎么加的压昼?在上述第2步求冷,蘋(píng)果用私鑰簽名我們本地公鑰時(shí),實(shí)際上除了簽名公鑰窍霞,還可以加上無(wú)限多數(shù)據(jù)(比如Devices匠题、Bundle Id),這些數(shù)據(jù)都可以保證是經(jīng)過(guò)蘋(píng)果官方認(rèn)證的但金,不會(huì)有被篡改的可能韭山。
可以想到把 允許安裝的設(shè)備 ID 列表 和 App對(duì)應(yīng)的 AppID 等數(shù)據(jù),都在第三步這里跟Mac公鑰一起組成證書(shū)冷溃,再用蘋(píng)果私鑰對(duì)這個(gè)證書(shū)簽名掠哥。在最后第 5 步驗(yàn)證時(shí)就可以拿到設(shè)備 ID 列表,判斷當(dāng)前設(shè)備是否符合要求秃诵。根據(jù)數(shù)字簽名的原理续搀,只要數(shù)字簽名通過(guò)驗(yàn)證,第 5 步這里的設(shè)備 IDs / AppID / 公鑰 L 就都是經(jīng)過(guò)蘋(píng)果認(rèn)證的菠净,無(wú)法被修改禁舷,蘋(píng)果就可以限制可安裝的設(shè)備和 App彪杉,避免濫用。
實(shí)際上一個(gè)“公鑰證書(shū)”本來(lái)就有規(guī)定的格式規(guī)范牵咙,公鑰證書(shū)派近,顧名思義就是對(duì)公鑰的簽名,上面我們把各種額外信息塞入證書(shū)里是不合適的洁桌,于是蘋(píng)果另外加了一個(gè)文件渴丸,叫 Provisioning Profile,一個(gè) Provisioning Profile 里就包含了證書(shū)以及上述提到的所有額外信息另凌,以及所有信息的簽名谱轨。這也是蘋(píng)果二次簽名(1. 對(duì)Mac公鑰簽名 2. 對(duì)Apple證書(shū)+Devices+Bundle ID+Entitlements簽名)的原因。
至此吠谢,我們知道了土童,Apple想限制安裝App的設(shè)備和限制安裝的App,于是增加了描述文件工坊,描述文件其實(shí)是對(duì)Apple證書(shū)献汗、Devices、 App Id王污、Entitlements等條款的簽名罢吃。
如下圖,是筆者畫(huà)的iOS開(kāi)發(fā)期的詳細(xì)的簽名和驗(yàn)簽的流程昭齐。其中涉及到Mac公鑰(CSR文件)刃麸、Mac私鑰、Apple公鑰(提前預(yù)置到iOS設(shè)備中)司浪、Apple私鑰(用于對(duì)Mac公鑰簽名)、Apple證書(shū)把沼、mobileprovison文件啊易。下面詳細(xì)介紹簽名和驗(yàn)簽的步驟。
簽名過(guò)程
- Mac公鑰上傳到Apple后臺(tái)進(jìn)行簽名饮睬,生成Apple證書(shū)
- Apple證書(shū)和App ID(bundle ID)租谈、Devices(iOS設(shè)備列表)、Entitlements(App權(quán)限列表)進(jìn)行組裝
- Apple后臺(tái)使用Apple私鑰對(duì)上面組裝的信息進(jìn)行簽名捆愁,生成一個(gè)后綴名為mobileprovision(描述文件)的文件
- Xcode 編譯項(xiàng)目生成App文件割去,然后使用Mac私鑰對(duì)App進(jìn)行簽名
- 上面第3、4步生成的.mobileprovision昼丑、簽名后的App共同組成了IPA安裝包
驗(yàn)簽過(guò)程
- iOS設(shè)備通過(guò)預(yù)置的Apple公鑰驗(yàn)證描述文件
- iOS設(shè)備通過(guò)預(yù)置的Apple公鑰驗(yàn)證Apple證書(shū)
- iOS設(shè)備通過(guò)第2步獲取的Mac公鑰驗(yàn)證App
這里再次不厭其煩的贅述下最終的流程:
- 在你的 Mac 開(kāi)發(fā)機(jī)器生成一對(duì)公私鑰呻逆,這里稱為公鑰L,私鑰L菩帝。L:Local
- 蘋(píng)果自己有固定的一對(duì)公私鑰咖城,跟上面 AppStore 例子一樣茬腿,私鑰在蘋(píng)果后臺(tái),公鑰在每個(gè) iOS 設(shè)備上宜雀。這里稱為公鑰A切平,私鑰A。A:Apple
- 把公鑰 L 傳到蘋(píng)果后臺(tái)辐董,用蘋(píng)果后臺(tái)里的私鑰 A 去簽名公鑰 L悴品。得到一份數(shù)據(jù)包含了公鑰 L 以及其簽名,把這份數(shù)據(jù)稱為公鑰證書(shū)简烘。
- 在蘋(píng)果后臺(tái)申請(qǐng) App ID苔严,配置好設(shè)備 UDID 列表和 App 可使用的權(quán)限,再加上第③步的證書(shū)夸研,組成的數(shù)據(jù)用私鑰 A 簽名邦蜜,把數(shù)據(jù)和簽名一起組成一個(gè) Provisioning Profile 文件,下載到 Mac 設(shè)備本地亥至。
- 在開(kāi)發(fā)時(shí)悼沈,編譯完一個(gè) App 后,用本地的私鑰 L 對(duì)這個(gè) App 進(jìn)行簽名姐扮,同時(shí)把第④步得到的 Provisioning Profile 文件打包進(jìn) APP 里絮供,文件名為
embedded.mobileprovision
,把 APP 安裝到手機(jī)上茶敏。 - 在安裝時(shí)壤靶,iOS 系統(tǒng)通過(guò)iOS設(shè)備內(nèi)置的公鑰 A,去驗(yàn)證
embedded.mobileprovision
的數(shù)字簽名是否正確惊搏,里面的公鑰證書(shū)簽名也會(huì)再驗(yàn)一遍贮乳。 - 確保了
embedded.mobileprovision
里的數(shù)據(jù)都是蘋(píng)果授權(quán)以后,就可以取出里面的數(shù)據(jù)恬惯,做各種驗(yàn)證向拆,包括用公鑰 L 驗(yàn)證App簽名,驗(yàn)證設(shè)備 ID 是否在 ID 列表上酪耳,AppID 是否和Apple后臺(tái)配置的Bundle ID對(duì)應(yīng)得上浓恳,權(quán)限開(kāi)關(guān)是否跟 App 里的 Entitlements 對(duì)應(yīng)等。如果上述數(shù)據(jù)都能夠?qū)?yīng)的上碗暗,說(shuō)明這個(gè)App的數(shù)據(jù)沒(méi)有被篡改颈将,允許安裝。
為什么從App Store下載安裝的App沒(méi)有mobileprovison文件言疗?
App發(fā)布的時(shí)候做了一系列的合法性驗(yàn)證(三次簽名)晴圾,當(dāng)我們把App上傳到App Store后,蘋(píng)果會(huì)用他自己的私鑰對(duì)app進(jìn)行重簽名噪奄。 這樣從app Store下載的app驗(yàn)證流程就變簡(jiǎn)單了:iOS 設(shè)備只需要用Apple預(yù)置的公鑰驗(yàn)證下載的App的數(shù)字簽名疑务。簽名驗(yàn)證通過(guò)說(shuō)明App沒(méi)有被篡改過(guò)沾凄,這樣就保證了App渠道的合法性和App的安全性。
為什么我們發(fā)布到App Store的App必須要被Apple重簽名知允?
因?yàn)榘l(fā)布到App Store的App需要安裝到很多用戶手機(jī)上撒蟀,也要保證用戶安裝的App沒(méi)有證書(shū)過(guò)期的問(wèn)題。這樣對(duì)證書(shū)有效期温鸽、可安裝的Devices列表都有不一樣的要求保屯。所以,App Store 的簽名驗(yàn)證方式和Xcode線下開(kāi)發(fā)以及企業(yè)分發(fā)的App的驗(yàn)證方式不一樣涤垫。我們上傳到App Store的App會(huì)被Apple重簽名姑尺,其重簽名的思路大致是:①先對(duì)ipa中的描述文件embedded.mobileprovision進(jìn)行驗(yàn)證,此步驟可以獲得Apple證書(shū)蝠猬,②然后再驗(yàn)證Apple證書(shū)切蟋,此步驟可以獲得Mac公鑰③再用上面一步獲得的Mac公鑰驗(yàn)證App是否被篡改過(guò)。如果以上三步都通過(guò)榆芦,則Apple會(huì)使用自己的Apple私鑰對(duì)App文件進(jìn)行重簽名柄粹。這樣用戶從App Store下載的App就不會(huì)有embedded.mobileprovision
文件,也就是它安裝和啟動(dòng)的流程是不依賴這個(gè)文件匆绣,驗(yàn)證流程也就跟Xcode驻右、In-House、AD-Hoc的驗(yàn)證流程不一樣了崎淳。
所以 App 上傳到 AppStore 后堪夭,就跟你的Apple開(kāi)發(fā)證書(shū)、Provisioning Profile 都沒(méi)有關(guān)系了拣凹,無(wú)論他們是否過(guò)期或被廢除森爽,都不會(huì)影響 App Store 上的安裝包。
那為什么發(fā)布 AppStore 的包還是要跟開(kāi)發(fā)版一樣搞各種證書(shū)和 Provisioning Profile嚣镜?
iOS App 簽名的原理中說(shuō)“猜測(cè)因?yàn)樘O(píng)果想做統(tǒng)一管理爬迟,Provisioning Profile 里包含一些權(quán)限控制,AppID 的檢驗(yàn)等祈惶,蘋(píng)果不想在上傳 AppStore 包時(shí)重新用另一種協(xié)議做一遍這些驗(yàn)證,就不如統(tǒng)一把這部分放在 Provisioning Profile 里扮匠,上傳 AppStore 時(shí)只要用同樣的流程驗(yàn)證這個(gè) Provisioning Profile 是否合法就可以了捧请。”
上面的猜測(cè)比較合理棒搜。筆者這里的補(bǔ)充是Apple需要對(duì)開(kāi)發(fā)者上傳大App Store的包進(jìn)行驗(yàn)證疹蛉。即保證開(kāi)發(fā)者上傳過(guò)程中App的文件信息沒(méi)有被中間人攻擊,所以這里Apple還是要求開(kāi)發(fā)者將App帶著各種證書(shū)和簽名上傳到Apple后臺(tái)力麸,Apple后臺(tái)再以拆快遞的方式對(duì)ipa包進(jìn)行各種合法性校驗(yàn)驗(yàn)證通過(guò)后再重簽名可款。
越獄中的重簽名
非越獄手機(jī)才會(huì)驗(yàn)證App的數(shù)字簽名育韩。越獄手機(jī)可以隨意安裝各種App且不會(huì)驗(yàn)證簽名,相當(dāng)于沒(méi)有了安全驗(yàn)證機(jī)制闺鲸。所以如果越獄開(kāi)發(fā)者把篡改后的App安裝到越獄手機(jī)筋讨,則不需要對(duì)App重簽名。 所以摸恍,改完的被篡改過(guò)mach-O的app文件不需要重簽名就可以運(yùn)行在越獄手機(jī)上悉罕。
正因?yàn)榉窃姜z手機(jī)會(huì)驗(yàn)證App的數(shù)字簽名,所以如果想把被修改過(guò)的app安裝到非越獄手機(jī)上立镶,需要對(duì)app進(jìn)行重簽名壁袄,目的就是讓被篡改過(guò)的App可以通過(guò)設(shè)備的對(duì)數(shù)字簽名的層層校驗(yàn)。
通常我們對(duì)App重簽名的方式有:
- 手動(dòng)重簽名
- iOS App Signer重簽名
- fastlane腳本重簽名
- MonkeyDev重簽名
參考文章
《圖解密碼技術(shù)》