hash
hash(哈希)算法是指將任意長度的文本,通過一個算法后得到一個固定長度的文本(也可能是二進制數據),哈希其實是一種思想,所有符合這種思想的算法都可以稱之為哈希算法(不如MD5,sha1,sha256)
哈希算法具有以下特點:
1. 相同的源文本,通過算法得到的結果必然相同
2. 不同的原文本,通過算法得到的結果必然不同(也有散列碰撞的情況不過概率很小)
3. 無法從結果反推出源文本
hash的應用:1.用戶密碼的加密2.搜索引擎3.版權/云盤秒傳功能4、數字簽名
數字簽名
實際上數字簽名就是把非對稱加密算法(RSA)和HASH算法結合起來用,比如我們有一篇文章需要傳輸,先用hash算法對文章運算得到hash值然后再用RSA私鑰對hash值加密得到密文,這個密文就是這篇文章的數字簽名,接收方用公鑰解密數字簽名得到發送方生成的hash 然后對文章進行hash運算得到hash值 這個值對比如果一致說明文章沒有被篡改過,不一致則說明文章被篡改了,數字簽名可以快速驗證文本的完整性和合法性。
數字證書
現實生活中的證書
證書說到底其實就是一個證明,像我們的畢業證書,學位證書就是教育局頒發給我們用來證明我們學歷文憑的,證書的組成部分:
- 證書獲得者:張三
- 內容:完成大學教育考試合格順利畢業
- 蓋章:教育部的鋼印
然后張三就可以去那著證書去找工作了,用人單位查看證書內容和鋼印,來驗證證書的真偽和判斷張三的學歷
不過現在有好多刻章辦證的也能做出來鋼印的效果,這樣用人單位就很難判斷證書的真偽了
數字證書:用數字簽名實現的證書
數字證書就是通過數字簽名實現的數字化證書,在證書的組成部分中還加入了其他信息比如證書有效期等。
跟現實生活中的簽發機構一樣,數字證書的簽發機構也有若干,并有不同的用處。比如蘋果公司就可以簽發跟蘋果公司有關的證書,而跟web訪問有關的證書則是又幾家公認的機構進行簽發。這些簽發機構稱為CA(Certificate Authority)。
對于被簽發人,通常都是企業或開發者。比如需要開發iOS的應用程序,需要從蘋果公司獲得相關的證書。這些申請通常是企業或者開發者個人提交給CA的。當然申請所需要的材料、資質和費用都各不相同,是由這些CA制定的,比如蘋果要求99或者299的費用。
之所以要申請證書,當然是為了被驗證。畢業證書的驗證方一般是用人單位;web應用相關的SSL證書的驗證方通常是瀏覽器;iOS各種證書的驗證方是iOS設備。我們之所以必須從CA處申請證書,就是因為CA已經將整個驗證過程規定好了。對于iOS,iOS系統已經將這個驗證過程固化在系統中了,除非越獄,否則無法繞過。
證書的授權鏈
數字證書可能還包括證書鏈信息。舉個例子:如果你要申請休假1周,需要你的上司審批,你的上司需要他的上司同意,最終需要大老板同意,那么這一層層的授權,形成了一個授權鏈,大老板是授權鏈的根(root),中間這些環節分別是被更接近root的人授權的。
我們從蘋果MC(Member Center)中獲得的證書實際也是一個包含有證書鏈的證書,其中的根是蘋果的CA。我們獲得的證書實際上是在告訴iOS設備:我們的證書是被蘋果CA簽過名的合法的證書。而iOS設備在執行app前,首先要先驗證CA的簽名是否合法,然后再通過證書中我們的公鑰驗證程序是否的確是我們發布的,且中途沒有對程序進行過篡改。
蘋果的應用簽名
蘋果為什么要搞應用簽名
在蘋果iOS系統出來之前,主流的操作系統Windows、安卓都不會限制應用程序的來源,隨便什么地方來的應用都可以安裝,這就造成了盜版引用泛濫,惡意程序橫行,蘋果為了解決這個問題也為了保證系統的安全性,必須對安裝的APP有絕對的控制權(也可能是為了收取每年$$99、$299這筆開發賬號費用)。
如果只是這樣事情會很簡單
我們的iPhone中和蘋果服務器中存在著一對RSA秘鑰(iPhone中存公鑰public key 蘋果服務器中存私鑰private key )
直接把我們提交上去的app生成一個用私鑰簽名的數字證書,每次安裝應用時再用iPhone上的公鑰驗簽,通過驗證的才給安裝就行了。
但實際情況要復雜的多,我們開發時調試應用、企業證書分發的應用也需要能安裝到手機上,這樣上面的辦法就行不通了,蘋果給出的答案是雙重簽名
雙重簽名流程
如下圖
流程如下:
- 把Mac電腦中的公鑰M(M:代表Mac)包裝成CSR文件在MC中向蘋果請求證書
- 蘋果服務器把CSR中的公鑰M取出來跟MC中的開發者賬號信息一起打包并使用蘋果服務器的私鑰A(A:代表Apple )進行簽名打包成證書
- 把證書包裝成描述文件并使用私鑰A簽名
- 在開發時,編譯完一個 APP 后,用本地的私鑰 M(今后你導出的P12) 對這個 APP 進行簽名,同時把第三步得到的證書一起打包進 APP 里,安裝到手機上。
- 在安裝時,iOS 系統取得證書,通過系統內置的公鑰 A,去驗證證書的數字簽名是否正確。
- 驗證證書后確保了公鑰M 是蘋果認證過的,再用公鑰 M 去驗證 APP 的簽名,這里就間接驗證了這個 APP 安裝行為是否經過蘋果官方允許。
接下來對每一步詳細說明:
什么是CSR文件(CertificateSigningRequest.certSigningRequest)
CSR文件(CertificateSigningRequest.certSigningRequest)這個文件是我們從鑰匙串申請來的為后面申請證書準備的,在MC中提交該文件向蘋果申請證書,這個文件主要包括兩部分內容:
1、申請者的信息,使用私鑰M加密
2、申請者的公鑰M,申請者使用的私鑰M對應的公鑰M
3、摘要算法(hash算法),RSA算法
我們可以用openssl來解析文件中的內容看看到底是個啥:
openssl asn1parse -i -in CertificateSigningRequest.certSigningRequest
0:d=0 hl=4 l= 638 cons: SEQUENCE
4:d=1 hl=4 l= 358 cons: SEQUENCE
8:d=2 hl=2 l= 1 prim: INTEGER :00
11:d=2 hl=2 l= 57 cons: SEQUENCE
13:d=3 hl=2 l= 22 cons: SET
15:d=4 hl=2 l= 20 cons: SEQUENCE
17:d=5 hl=2 l= 9 prim: OBJECT :emailAddress
28:d=5 hl=2 l= 7 prim: IA5STRING :xxx.com
37:d=3 hl=2 l= 18 cons: SET
39:d=4 hl=2 l= 16 cons: SEQUENCE
41:d=5 hl=2 l= 3 prim: OBJECT :commonName
46:d=5 hl=2 l= 9 prim: UTF8STRING :宋XX
57:d=3 hl=2 l= 11 cons: SET
59:d=4 hl=2 l= 9 cons: SEQUENCE
61:d=5 hl=2 l= 3 prim: OBJECT :countryName
66:d=5 hl=2 l= 2 prim: PRINTABLESTRING :CN
70:d=2 hl=4 l= 290 cons: SEQUENCE
74:d=3 hl=2 l= 13 cons: SEQUENCE
76:d=4 hl=2 l= 9 prim: OBJECT :rsaEncryption
87:d=4 hl=2 l= 0 prim: NULL
89:d=3 hl=4 l= 271 prim: BIT STRING
364:d=2 hl=2 l= 0 cons: cont [ 0 ]
366:d=1 hl=2 l= 13 cons: SEQUENCE
368:d=2 hl=2 l= 9 prim: OBJECT :sha256WithRSAEncryption
379:d=2 hl=2 l= 0 prim: NULL
381:d=1 hl=4 l= 257 prim: BIT STRING
可以看到文件包含了我的信息,并標明使用了sha256摘要算法和RSA公鑰加密算法。蘋果的MC在拿到這個后,將這個信息記錄下來,并簽發出相關的證書。這里,蘋果實際無需驗證我的信息,因為如果我不交錢就沒辦法上傳這個文件,也就得不到證書。
在MC中申請的證書是什么
蘋果取出CertificateSigningRequest.certSigningRequest中的公鑰,然后將我的MC賬號信息和我提交的公鑰封裝在證書中,并進行數字簽名。以開發證書為例,以開發證書為例我們用openssl打開看一下內容:
openssl x509 -inform der -in ios_development.cer -noout -text
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 8261114673414944075 (0x72a56006b5aa354b)
Signature Algorithm: sha256WithRSAEncryption
Issuer: C=US, O=Apple Inc., OU=Apple Worldwide Developer Relations, CN=Apple Worldwide Developer Relations Certification Authority
Validity
Not Before: Jun 15 06:59:13 2020 GMT
Not After : Jun 15 06:59:13 2021 GMT
Subject: UID=H34NZV9396, CN=iPhone Developer: shen dongqu (J4NH894YDN), OU=X8H9B4P8L2, O=ZhongChu NanJing ZhiHuiWuLiu KeJi CO.LTD, C=CN
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
Modulus:
00:cd:58:f1:21:b2:82:95:e6:7a:4c:72:70:9d:06:
12:97:ed:a0:5c:d2:43:e0:f8:96:33:34:ef:a2:62:
6e:59:fc:e3:b0:08:5b:0b:9c:d6:4b:37:1e:22:46:
32:71:67:b4:ca:14:4a:94:a6:4f:46:b7:b6:f8:bd:
e6:8e:f9:f6:a5:0a:9a:24:7f:0d:71:d0:c7:c4:19:
be:f9:a4:de:42:1f:22:e2:17:ed:3c:13:00:9c:62:
d5:ea:6d:86:9d:6c:6c:90:ae:ea:55:24:f0:00:08:
ed:17:cd:d3:cf:40:6d:a7:11:22:c3:cc:24:e0:4a:
70:9a:36:8b:ea:f4:e0:42:4c:68:28:69:b0:fa:9b:
58:59:ae:58:c3:c2:25:2a:07:ac:c2:ad:53:55:f9:
3b:fe:ac:7d:9b:cf:e2:15:ff:c9:e7:eb:ec:27:9a:
e3:e9:34:47:d3:1f:68:92:28:14:26:68:0c:13:34:
53:ce:a3:03:a8:db:af:2b:3e:2f:45:59:73:6b:42:
23:f2:db:81:b3:e4:11:56:3f:2a:db:96:5e:a1:83:
32:75:b5:c9:be:1f:bb:9f:49:62:af:63:c8:11:f7:
a2:ae:a6:25:2e:69:c5:ff:73:6c:20:da:62:de:0a:
27:0d:24:af:da:30:37:ad:d1:7f:97:5a:06:4a:23:
fa:53
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Basic Constraints: critical
CA:FALSE
X509v3 Authority Key Identifier:
keyid:88:27:17:09:A9:B6:18:60:8B:EC:EB:BA:F6:47:59:C5:52:54:A3:B7
Authority Information Access:
OCSP - URI:http://ocsp.apple.com/ocsp03-wwdr01
X509v3 Certificate Policies:
Policy: 1.2.840.113635.100.5.1
User Notice:
Explicit Text: Reliance on this certificate by any party assumes acceptance of the then applicable standard terms and conditions of use, certificate policy and certification practice statements.
CPS: http://www.apple.com/certificateauthority/
X509v3 Extended Key Usage: critical
Code Signing
X509v3 Subject Key Identifier:
5C:FF:A1:74:3A:8C:64:9B:38:35:7A:D4:14:53:6E:05:F2:00:1A:55
X509v3 Key Usage: critical
Digital Signature
1.2.840.113635.100.6.1.2: critical
..
Signature Algorithm: sha256WithRSAEncryption
79:99:29:82:ed:80:3b:5a:6f:f6:5f:53:d0:7b:79:29:0f:46:
40:a2:e4:c8:3f:f5:c9:09:0b:7a:ec:f9:be:9e:50:6a:fa:83:
9e:c0:78:74:77:eb:6d:7b:21:df:ca:36:91:79:9a:71:0e:bb:
a6:41:fb:0a:71:58:b4:b7:b4:f5:00:a0:bb:ca:60:ef:4d:56:
82:53:ce:38:8d:55:37:ec:65:b1:13:bd:2d:5c:5c:e9:59:65:
58:d0:c7:bf:be:84:99:31:77:32:80:a2:57:e1:f4:54:46:7e:
ad:f2:46:fe:6c:ed:d9:9f:e0:50:b8:91:a1:14:e2:48:dd:2f:
37:80:02:93:db:93:50:27:07:c7:83:ae:b6:5b:4d:ab:dd:41:
e4:bd:80:21:30:c1:c4:f8:bf:41:f3:e6:0f:5d:6a:39:56:cd:
0a:d4:ab:27:d3:0f:ae:97:d1:a1:a4:b3:c7:8a:3b:d8:6a:28:
49:92:76:6f:4c:06:75:96:73:4d:24:bf:50:65:31:80:73:08:
dd:87:74:6e:b9:9e:e2:0a:0f:25:37:a5:4e:72:4a:e5:c6:93:
9a:36:8c:ac:a6:1e:1f:74:58:e7:20:5b:1f:e5:31:6c:96:34:
d8:50:b9:b3:92:72:1a:57:9a:e6:c3:dc:3c:c2:f9:53:27:90:
2b:2b:60:39
Data域即為證書的實際內容,與Data域平級的Signature Algorithm實際就是蘋果的CA的公鑰,而摘要的簽名應該沒有顯示出來。Data域下一級的內容就是我的蘋果賬號信息,其中最為重要的是我的公鑰,這個公鑰與我本機的私鑰是對應的。當我們雙擊安裝完證書后,KeyChain會自動將這對密鑰關聯起來,所以在KeyChain中可以看到類似的效果:
[圖片上傳失敗...(image-9f53db-1613977335577)]
程序跑到真機上的時候就是用這個私鑰M給程序包簽名的,而公鑰M會隨著描述文件(.mobileprovision)一起打進app中。
所以,就算你有證書,但是如果沒有對應的私鑰是沒有用的。而團隊開發則需要通過.p12文件把這個私鑰分享給團隊其他成員。
iOS授權和描述文件
有了證書蘋果可以確保app是自己授權的開發者提交的以及app的完整性,但是這樣只能確保本app是安全的,并不能細化到APP所使用的某些服務是被蘋果認可的,不如APNS推送,定位等,而且證書也無法限制調試版應用的裝機規模,于是蘋果推出了mobileprovision描述文件。可以使用命令查看mobileprovision:
security cms -D -I embedded.mobileprovision
mobileprovision文件包含:
- AppId。每個app必須在MC中創建一個對應的AppId。規則不累述了。
- 使用哪些證書。上面說了,不同類型的證書就代表了不同的發布方式,還包括一些功能的能否使用(比如APN)
- 功能授權列表
- 可安裝的設備列表。對于AdHoc方式發布的app或者真機調試時,會有一個列表,這個列表里面是iOS設備的UDID,每臺iOS設備出廠的UDID都不同,所以可以用來標識設備。可通過iTunes連接設備,或者http://fir.im/udid這里獲取
-
蘋果的簽名!
注意5,這里的簽名是蘋果簽的,跟我們的私鑰沒有關系。也就是說mobileprovision文件是蘋果簽名的,我們除了從MC中獲取,別無他法。也不能再獲取后隨意篡改(比如添加別的設備)。因此上面的1-4就被蘋果牢牢的控制在手里,所有的規則都必須由蘋果來制定和約束。
最終程序包變成了這個樣子:
image.png
應用重簽名
iOS程序最終都會以.ipa文件導出,先來了解一下ipa文件的結構:
事實上,ipa文件只是一個zip包,可以使用如下命令解壓:
/usr/bin/unzip -q xxx.ipa -d <destination>
解壓后,得到上圖的Payload目錄,下面是個子目錄,其中的內容如下:
- 資源文件,例如圖片、html、等等。
- _CodeSignature/CodeResources。這是一個plist文件,可用文本查看,其中的內容就是是程序包中(不包括Frameworks)所有文件的簽名。注意這里是所有文件。意味著你的程序一旦簽名,就不能更改其中任何的東西,包括資源文件和可執行文件本身。iOS系統會檢查這些簽名。
- 可執行文件。此文件跟資源文件一樣需要簽名。
- 一個mobileprovision文件.打包的時候使用的,從MC上生成的。
- Frameworks。程序引用的非系統自帶的Frameworks,每個Frameworks其實就是一個app,其中的結構應該和app差不多,也包含簽名信息CodeResources文件
重簽名工具:codesign
需要砸過殼的ipa包(可以在PP助手里下載,也可以在越獄手機里自己砸殼)
相關命令:
- codesign -vv -d XXX.app 查看app包的簽名信息
- security find-identity -v -p codesigning 列舉出電腦中安裝過的證書
- otool -l XXX (> ~/Desktop/111.txt 重定向輸出 | grep cry 查詢條件) 查看MachO文件的信息(器重cryptid標識是否加密0標識沒有加密已經砸過殼了,其他值已經加密,是appStore加密的用的對稱加密算法,程序運行的時候iPhone手機會把包解密到手機內存中,加密是為了應用代碼安全防止逆向工程師查看應用的匯編代碼)
- codesign -fs "證書名稱" XXX 使用“證書” 重簽 XXX(--no-strict --entitlements=XXX.plist 該參數使用權限文件XXX.plist進行重簽)
- security cms -Di embedded.mobileprovision 查看描述文件信息
- Zip –ry 輸出文件 輸入文件 將輸入文件壓縮為輸出文件(例如Zip -ry XXX.ipa Payload )
重簽步驟:
- 刪除調無法重簽的東西包括1.插件Plugins文件夾下的所有插件2.Watch目錄下的文件(因為免費的證書功能沒有那么強大,簽不動這些東西)
- 簽Frameworks目錄下的frameworks(查看MachO文件是否有可執行權限(黑色表示有權限 白色標識沒有權限 沒有的話 chmod + x MachO名稱))
- 添加描述文件(需要新建一個工程build一下去.app中把embedded.mobileprovision復制粘貼到MachO同級目錄下)
- 修改info.plist中的bundleId 改成跟描述文件里的一致
- 簽名整個app包(需要用到證書和第三步中描述文件的授權信息,授權信息就是描述文件中Entitlements字段,復制到一個新的plist里就行)
- 重新打包
搞個流程圖:
iOS設備如何驗證app是否合法
關鍵的幾個點:
- 解壓ipa
- 取出embedded.mobileprovision,通過簽名校驗是否被篡改過
2.1 其中有幾個證書的公鑰,其中開發證書和發布證書用于校驗簽名
2.2 BundleId
2.3 授權列表 - 校驗所有文件的簽名,包括Frameworks
- 比對Info.plist里面的BundleId是否符合embedded.mobileprovision文件中的
利用Xcode進行重簽
使用Xcode重簽會簡單很多
步驟:
- 使用Xcode新建一個同名工程(跟需要重簽的.app同名 不同名的話Xcode會再自動生成一個同名的MachO文件,需要重簽的MachO會被忽略),build一下,然后把Products目錄下的.app替換成需要重簽的.app包
- 刪除無法重簽的
- 重簽Framews下的文件
然后直接運行Xcode會自動重簽安裝到手機上,.app包中info.plist的BundleId會被Xcode自動修改,方便的一批
小知識點使用Xcode調試手機上正在運行的應用數據線連接手機Xcode選擇Debug -> Attach to Process -> 應用名 等待Xcode狀態變為Running 就可以調試了
有時候重簽的時候會報錯提示:resource fork, Finder information, or similar detritus not allowed
這個cd到.app所在的目錄執行命令:xattr -rc .
就可以了