應用簽名--數字簽名?程式碼簽名?雙層程式碼簽名?

應用簽名
數字簽名
數字簽名(又稱 公鑰 數字簽名、 電子簽章 等)是一種類似寫在紙上的普通的物理簽名,但是使用了公鑰加密領域的技術實現,用於鑑別數字資訊的方法。一套數字簽名通常定義兩種互補的運算,一個用於簽名,另一個用於驗證。
數字簽名,就是隻有資訊的傳送者才能產生的別人無法偽造的一段數字串,這段數字串同時也是對資訊的傳送者傳送資訊真實性的一個有效證明。
數字簽名技術 是將摘要資訊用傳送者的私鑰加密,與 原文 一起傳送給接收者。接收者只有用傳送者的公鑰才能解密被加密的摘要資訊,然後用 Hash函式 對收到的 原文 產生一個摘要資訊,與解密的摘要資訊對比。如果相同,則說明收到的資訊是完整的,在傳輸過程中沒有被修改,否則說明資訊被修改過,因此數字簽名能夠驗證資訊的完整性。
舉個例子:移動客戶端向伺服器傳送資料

客戶端傳送資料
如果不做任何處理,可能會遭到中間人的竊取攻擊,後果如何嚴重就不說了。那麼我們如何防止中間人攔截,或者檢查資料是否被篡改呢?
直接用RSA(RSA加密原理)進行加密應該是不滿足我們的需求,RSA只適合對小資料進行加密,我們知道驗證資料的完整性可以用Hash(Hash概述)來驗證,可以對資料進行Hash,把Hash值和原始資料一起打包傳送給伺服器,伺服器將原始資料進行Hash,得到的hash值和客戶端傳送的Hash值做對比,如果一致則保證資料有效性。但是這樣會有安全隱患,如果中間人篡改了客戶端傳送的資料,當然也可以修改客戶端傳送的Hash值,所以這樣操作不可行。
這時我們可以用RSA來對hash值進行保護,此時客戶端傳送原始資料,和經RSA加密後的該資料的hash值。

數字簽名
伺服器對RSA加密的資料進行解密,得到原始資料的hash值,接下來對原始資料進行通過同樣的Hash演算法,將得到的Hash值和解密後的Hash值做對比,如果一致則保證資料有效性,整個過程中,如果解密的Hash值和原始的Hash值不一致,或者無法解密RSA的資料,說明資料被篡改了。

3.jpg
現在我們解決了服務端收到客戶端傳送資料的有效性,此時我們稱,對原始資料Hash值進行RSA加密後的資料,是原始資料的數字簽名。簡單解釋數字簽名也就是對原始資料的Hash值進行非對稱加密。
程式碼簽名
程式碼簽名是對可執行檔案或指令碼進行數字簽名,用來標識軟體來源以及軟體開發者的真實身份,確認軟體在簽名後未被修改或損壞的措施。和數字簽名原來一樣,只不過簽名的資料是程式碼而已。
蘋果也是通過程式碼簽名來保證每一個安裝到iOS上的APP都是經過蘋果官方允許的,防止盜版軟體、病毒入侵、靜默安裝等。如果想要實現驗證,最簡單的方式就是通過蘋果官方生成非對稱加密的一對公私鑰,在iOS系統中內建一個與伺服器對應的公鑰,私鑰由蘋果後臺來儲存,我們傳APP到App Store時,蘋果後來用私鑰對APP資料進行簽名,iOS系統下載這個APP後,用公鑰驗證這個簽名,如果簽名正確則這個APP肯定是由蘋果後臺認證的,並且沒有被修改或損壞。

程式碼簽名
整個過程很簡單,這樣就保證了蘋果安裝的每一個APP都是經過蘋果官方允許的。對於大部分普通使用者而言,這樣一個數字簽名就解決了安全隱患問題,但是實際上iOS裝置安裝APP並不是只有App Store這一個渠道,比如對於我們iOSer來說,我們在開發APP時還在真機除錯,當然蘋果還開放了企業內部分發的渠道,這時就無法通過簡單的程式碼簽名來滿足這些需求了。
蘋果為了實現這些需求,iOS簽名的複雜度也就開始增加了,這樣雙層程式碼簽名就出現了。前提,我們都知道描述檔案,但是描述檔案具體是幹嘛的呢
描述檔案
在真機除錯時候,都會有一個描述檔案,描述檔案就是在developer.apple.com建立的,在Xcode中填入AppID後會代辦建立,Xcode執行時會打包進APP中。為了系統安全,蘋果除了控制APP濫用問題還控制了推送、iCloud、偵錯程式等附加這些許可權,蘋果把這些許可權開關統一稱為Entitlements(授權檔案)。並將這個檔案放在了一個叫做Provisioning Profile(描述檔案)檔案中,描述檔案裡面就包括許可權、證書等配置相關檔案。
通常,描述檔案會儲存在~/Library/MobileDevice/Provisioning Profiles/這個檔案中,可以在終端用 security cms -D -i + [名稱]命令檢視描述檔案裡面的資訊,我們會發現,描述檔案是一個plist檔案,下面是個人描述檔案資訊演示,並對一些資訊做出了註釋,部分關鍵內容被隱藏,Base64(瞭解Base64編碼解碼)內容被刪減
$ security cms -D -i 294b2de0-a877-4f33-9825-9a8***.mobileprovision <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>AppIDName</key> <string>com *** </string> <key>ApplicationIdentifierPrefix</key> <array> <string>***GCDB</string> </array> <key>CreationDate</key> <date>2019-03-06T08:54:06Z</date> <key>Platform</key> <array> <string>iOS</string> </array> <key>IsXcodeManaged</key> <true/> <key>DeveloperCertificates</key> <array> <data>***vcNAQELBQAwgZYxCzAJBgNVBAYTAlVTMRMwEQYDVQQKDApBcHBsZSBJbmMuMSwwKgYDVQQLDCNBcHBsZSBXb3JsZHdpZGUgRGV2ZWxvcGVyIFJlbGF0aW9uczFEMEIGA1UEAww7QXBwbGUgV29ybGR3aWRlIERldmVsb3BlciBSZWxhdGlvbnMgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTgwNzEwMDIzNsb3BtZW50IENvLixMdGQuMQswCQYDVQQGEwJVUzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAO4xNm+/SXHwULul2Am4b+2/a919AfaDSy6Jw+nC3599RNhUlY+/PNTudcsBUsSw53+flAh6dVVGO77lebM1GaveXMLr65l9aZe2a6ewR0QOpSkvoBZBXlRA14WpyfdMbU7VlWutKiFHsuxA4KSQyoagY8GJ3tB5vSlxRtfix0TKtOCMx9v1iYdCztmhmtt5J6GZn8jKszkPgKxMNvm4MD9N/pr7/Z0gX06oywYb3DpS7uQKdffsLZyj05H0HvSg6V4nHZw5HNIf8qd1VjOiI7NGcvsOwltfGmiOhmxQjaESwalgX7vWg7ij8fh9ke1on8veQgptIxutKjLWG9JnJ2LPOeP7w3PJC03Yl89qJ6F0VAyA1+ck1ieimrG0yXkd9z/YWMd/puDoW7SmEQ/WdKyQkyld0iSnkQ90511uOAp0/yDgaaouyUDZlcIjL2/4JzdEJEiRkZEdmw63uYe4dwXSyTyLlA+ntka2QlKEiJmy8oyPTqjEuqcWWQmnFYWiEBqPaeEXlXT9uuGjqn9aN3MaTgD8QFIyOhonc6ReQHtx8apXGEzhVNAQXCLuKSB04JiCbL3YE2XT42QlygBL+7ROxC00pAIltrPkFfuoyBbpnj9pWQ==</data> <data>***GVyIFJlbGF0aW9uczFEMEIGA1UEAww7QXBwbGUgV29ybGR3aWRlIERldmVsb3BlciBSZWxhdGlvbnMgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTgwNTI1MTMxMjA4WhcNMTkwNTI1MTMxMjA4WjCBrjEaMBgGCgmSJomT8ixkAQEMCjVFVE45NEpBNlUxMTAvBgNVBAMMKGlQaG9uZSBEZXZlbG9wZXI6IFhpbiBDaGVuZyAoNEU4Mk5RVzZDMikxEzARBgNVBAsMClpFV0pNSEdDREIxOzA5BgNVBAoMMlNoYW5naGFpIFJpc2VuIEVsZWN0cmljIFBvd2VyIERldmVsb3BtZW50IENvMDYGCCsGAQUFBwIBFipodHRwOi8dEU39NyqZsQBCA/P1txkkx9sI7JsMcMnjwa/N5QCg+gJLvMEh1ZvQ/rroTtyvDxFuuMrQkiZeeBGs8qBO2Jre6ma32mMo5kSjc9w9AtnFwlQHrW3+HPwwqlThRrMeNvbLZAvZhoENb04HE26sH4k1tk8CrNvutsjl+K3GGnuvWCnZy/dT57wrGAMrlkQZRWXomSxr9y+F4ArsMj+4UsA==</data> <data>***sZHdpZGUgRGV2ZWxvcGVyIFJlbGF0aW9uczFEMEIGA1UEAww7QXBwbGUgV29ybGR3aWRlIERldmVsb3BlciBSZWxhdGlvbnMgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTgwNTEzMDQ1OTQ0WhcNMTkwNTEzMDQ1OTQ0WjCBrjEaMBgGCgmSJomT8ixkAQEMCjVFVE45NEpBNlUxMTAvBgNVBAMMKGlQaG9uZSBEZXZlbG9wZXI6IFhpbiBDaGVuZyAoNEU4Mk5RVzZDMikxEzARBgNVBAsMClpFV0pNSEdDREIxOzA5BgNVBAoMMlNoYW5naGFpIFJpc2VuIEVsZWN0cmljIFBByYWN0aWNlIHN0YXRlbWVudHMuMDYGCCsGAQUFBwIBFipodHRwOi8vd3d3LmFwcGxlLmNvbS9jZXJ0aWZpY2F0ZWF1dGhvcml0eS8wFgYDVR0lAQH/BAwwCgYIKwYBBQUHAwMwHQYzizUHwwrgDSFxwfGfc71fr4hz3PmN6o7XqtGcNO4Af49JdDMZv6VQ5mr/plPBSDdun0D5ZfNDr9cXopDCzy+XPZB/H1ARmy1MT4vuKvdsGuUKBvJX/HinDi38G6AuwZ0alfPY9xqJ7WB7K14kaVdaaqOHMThOA7b7b1Stu+MjAKYJ6aUkrf9vvDbDAkQFi8lfh4L3Vya9MoXEpDpCNxQrUJhc6sy2eMf1NT5Q==</data> <data>***zA5BgNVBAoMMlNoYW5naGFpIFJpc2VuIEVsZWN0cmljIFBvd2VyIERldmVsb3BtZW50IENvLixMdGQuMQswCQYDVQQGEwJVUzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKIWs9nQdTq3yqKLYVmjrGrgh6MhaWlkZb5MeHWKwGfky3/n/FaXmrLNxFFFWeFihdg4zmFjSjRl8ccvPF3afdZU2qW4Co1aKu459CnPhknFNbFtcrs0V1T6u6p3RJn6togsWn1z33IakruJPYtwY7k4S5jb20vb2NzcDAzLXd3ZHIwMTCCAR0GA1UdIASCARQwggEQMIIBDAYJKoZIhvdjZAUBMIH+MIHDBggrBgEFBQcCAjCBtgyBs1JlbGlhbmNlIG9uIHRoaXMgY2VydGlmaWNhdGUgYnkgYW55IHBhcnR5IGFzc3VtZXMgYWNjZXB0YW5jZSBvZiB0aGUgdGVAFqGwKrYTc+8/GyszOm3u4/mn5s5b58ORnITE+A9bNtDGv6Qz46ev3ZMCrQZFwye//Tk+BI7ms4++jkj/pcmUCULtZw178cTRBpMT4P7tzgH5mRP/BpcSd/rv8994UXYPYdpXa4epFhchlCvu8dT8sQ38fFeahyd85nS30c4RxyW32bzKnzzRSedr/j4Y1qIIvzKdWPcnwkA5RYH8naxYfzEXL2321tdwfR5skvApeP/S2oX9WC+18XBk8Yy693rJoqrKdwkOzQSVGcA==</data> <data>***3NjZOMlBGS00xMzAxBgNVBAMMKmlQaG9uZSBEZXZlbG9wZXI6IEhhb3lhbmcgWmh1IChLTU5VVTI4QlBaKTETMBEGA1UECwwKWkVXSk1IR0NEQjE7MDkGA1UECgwyU2hhbmdoYWkgUmlzZW4gRWxlY3RyaWMgUG93ZXIgRGV2ZWxvcG1lbnQgQ28uLEx0ZC4xCzAJBgNVBAYTAlVTMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA19bNzMNJ0uSYvwNygYH8b4GQY11UmNvbS9vY3NwMDMtd3dkcjAxMIIBHQYDVR0gBIIBFDCCARAwggEMBgkqhkiG92NkBQEwgf4wgcMGCY2QGAQIBAf8EAgUAMA0GCSqGSIb3DQEBCwUAA4IBAQCJw3MoEbhJNVyc1PFG6FtY7QZAy+gmqRz9YiwnFh3y5Qj5lnC2n0WdG8SrlZA+TKQgfwRZNEB6ZIfDZOJAFsqpBMAauC1V0CDzP8UWBDfluoVCU89Ns5juag8ffk/ulEQfEN1NakgiSwihy+QEmd2PWBTn4dfGVSV9mYRjPppFdM6kik1WLgMDZfLRmNzZ0MzMZMAPy8gdMmQiM7uBY1v+EnUXfyjKnK7Y28AB9c6oQHPoTGmVQxZjJgkejyOlBPWwVPbNvvzNRPuBaHI8muX2HzjsA9SJowEBXKICinqLSFZ8NDQVBrw2fgDs5MD5vaDHXtrz9t6Ahw6/7nUB240U</data> <data>***LDCNBcHBsZSBXb3JsZHdpZGUgRGV2ZWxvcGVyIFJlbGF0aW9uczFEMEIGA1UEAww7QXBwbGUgV29ybGR3aWRlIERldmVsb3BlciBSZWxhdGlvbnMgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTgwOTI1MDIxMzA4WhcNMTkwOTI1MDIxMzA4WjCBrzEaMBgGCgmSJomT8ixkAQEMCjIzVDNTWlo0WjQxMjAwBgNVBAMMKWlQaG9uZSBEZXZlbG9wZXI6IOS9s+a7qCDnjosgKDN1UdDgQWBBT7im/bw3RlTv0soM/RVB2mmh9e4zAOBgNVHQ8BAf8EBAMCB4AwEwYKKoZIhvdjZAYBAgEB/wQCBQAwDQYJKoZIhvcNAQELBQADggEBACErmsYfmt/qn5yj86poEkDsDWhznabHVn1CJprtzyHbXNcbKJE1pY99ACzSUVW9iGaxXJ9m5dWmZsd+2gxOBthFDq4mSpU50OHQgg9AjjugvsQ+OH1r1qgqcJMPdLN4stJtkAC9Mb/rt3AYA5eEdHOXbhrsE3TXWmWfJzYS9PFyarGcJ9xFAWg76jTtFA6nlzYtl/YyMDS6Z075oMzKG/pRfCI13P4AqRKdx/DBtz4x0Wv59LVMVrXa4bfePLKMBJrBFdiiyCy4k4BIx4weG/Y/8OsEkmWkN0fDWmi4MZjy3I+FCNkv9tUzI/vRvDEiNR7qo5rGRKnAi+X1QbdLYcU=</data> <data>***o0WjQxMjAwBgNVBAMMKWlQaG9uZSBEZXZlbG9wZXI6IOS9s+a7qCDnjosgKDNYTDJNRFdWOUcpMRMwEQYDVQQLDApaRVdKTUhHQ0RCMTswOQYDVQQKDDJTaGFuZ2hhaSBSaXNlbiBFbGVjdHJpYyBQb3dlciBEZXZlbG9wbWVudCBDby4sTHRkLjELMAkGA1UEBhMCVVMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC35nKt/AoSiANJn9e9H96rol/85zSEAjAAMB8GA1UdIwQYMBaAFIgnFwmpthhgi+zruvZHWcVSVKO3MD8GCCsGAQUFBwEBBDMwMTAvBggr1UdJQEB/wQMMAoGCCsGAQUFBwMDMB0GA1UdDgQWBBSIeBiIaX4EyW39H2laObRLnSyWVjAOBgNVHQ8BAf8EBAMCB4AwEwYKKoZIhvdjZAYBAgEB/wQCyETSZ/FOr8EBZBVLmMGXz03x6f2Hpd7QsmoJJM5+6hHu4qgstgXNg0RRsa0B4jScKTMlRxmdZuLjm3plaX+P+yo0ylAnvGWm1sx9mxPTgrDbUg7Rg0n1bhrBtkX47+r8SUz4+E6dHnqZ7x48hZlhv6SFkj4PQ/apeAvITvnLeq7bj586gkpwS30bjmrsqSO8aEnysvyxq6Xx3+seH9Uihmjb7XdnV25mKfbf5ms6sm+HrN6ifrDb0LePX8YAsSH4=</data> </array> <key>Entitlements</key>// 許可權 <dict> <key>keychain-access-groups</key> <array> <string> *** .*</string> </array> <key>get-task-allow</key>// APP是否允許除錯 <true/> <key>application-identifier</key>// appID <string> *** </string> <key>com.apple.developer.associated-domains</key> <string>*</string> <key>com.apple.developer.team-identifier</key> <string> *** </string> <key>aps-environment</key> <string>development</string> </dict> <key>ExpirationDate</key>// 過期時間 <date>2020-03-05T08:54:06Z</date> <key>Name</key> <string>iOS Team Provisioning Profile: *** </string> <key>ProvisionedDevices</key>// 裝置列表 <array> <string>476c21e91700a0605a11a***3de7705a</string> <string>98a1263783fb5538ec292f0***9d05690ffb</string> <string>bc9144d7496e5337e1f***cb653dc42e</string> <string>254fbcad0126f989b8980***d1dd8169b6ca</string> <string>349f7aeb300473cc30c28***025d</string> </array> <key>TeamIdentifier</key> <array> <string> *** </string> </array> <key>TeamName</key> <string> *** Co.,Ltd.</string> <key>TimeToLive</key> <integer>365</integer> <key>UUID</key>// 描述檔案的UUID <string> *** </string> <key>Version</key> <integer>1</integer> </dict>
雙層程式碼簽名
-
請求證書
開發過程中,首先Mac電腦(比如Xcode)會自動生成一對公私鑰

公私鑰
圖中的證書就是公鑰M,專用金鑰就是私鑰M(也就是我們匯出的P12檔案)
用一個CSR檔案(就是在鑰匙串訪問中,證書助理,從證書頒發機構中獲取的)向蘋果申請一個證書,這個CSR檔案主要包含了一個公鑰檔案,還有一些資訊,比如郵箱、名字、簽名信息、Hash值等等,蘋果收到請求後,會用私鑰A將公鑰M進行簽名,以供蘋果裝置進行驗證(用公鑰A進行驗證)。蘋果伺服器將公鑰M和簽名信息打包成證書,並把appID、證書、裝置IDs、許可權檔案等放入描述檔案一併返回給Mac電腦,以備Mac電腦用這個描述檔案中的證書到iOS裝置去驗證。

請求證書
-
生成IPA檔案,傳送到iOS裝置上
iOS裝置上的APP其實都是資料夾,最重要的是可執行檔案MachO和framework,APP簽名也就是對它倆進行簽名,通過Mac電腦的私鑰M對檔案進行簽名,把這個簽名和從蘋果申請的描述檔案一併放入到APP中。當安裝APP時,iOS裝置用公鑰A來解析描述檔案中的證書進行驗證證書的有效性,通過之後將證書中的公鑰M拿出來,再去驗證APP簽名的有效性,這樣就可以驗證當前APP是否是蘋果官方允許的。

雙層程式碼簽名
在開發階段,我們需要頻繁的改動程式跑真機,蘋果不需要關心這些,所以iOS裝置沒有對APP的更改進行驗證,只是驗證證書(公鑰M是不是合法的,APP簽名的有效性)。這樣解決了安裝問題,但是如果這樣的話,可以在任何一部iOS裝置上安裝APP,蘋果防止開發者濫用,又加了兩個限制:
- 要在蘋果後臺註冊過的裝置才可以安裝
- 簽名只能針對具體的某一個APP進行簽名
關於APP簽名
在開發中,編譯一個APP後,用本地的私鑰M對APP進行簽名,同時把從蘋果伺服器得到的Provisioning Profile檔案打包進APP中,檔名為embedded.mobileprovision,把APP安裝到iOS裝置後,系統進行驗證。

檢視資原始檔簽名
檢視APP的包內容,裡面會有_CodeSignature資料夾(裡面的就是資原始檔的簽名),還有個可執行檔案,可以用MachO檢視,裡面的Code signature就是應用簽名。
該文章為記錄本人的學習路程,希望能夠幫助大家,也歡迎大家點贊留言交流!!!文章地址: https://www.jianshu.com/p/4307de384a50