iOS應用簽名原理--數字簽名?代碼簽名?雙層代碼簽名?

應用簽名

數字簽名

數字簽名(又稱公鑰數字簽名、電子簽章等)是一種類似寫在紙上的普通的物理簽名,但是使用了公鑰加密領域的技術實現,用於鑑別數字信息的方法。一套數字簽名通常定義兩種互補的運算,一個用於簽名,另一個用於驗證。
數字簽名,就是隻有信息的發送者才能產生的別人無法僞造的一段數字串,這段數字串同時也是對信息的發送者發送信息真實性的一個有效證明。

數字簽名技術是將摘要信息用發送者的私鑰加密,與原文一起傳送給接收者。接收者只有用發送者的公鑰才能解密被加密的摘要信息,然後用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,蘋果防止開發者濫用,又加了兩個限制:

  1. 要在蘋果後臺註冊過的設備纔可以安裝
  2. 簽名只能針對具體的某一個APP進行簽名

關於APP簽名

在開發中,編譯一個APP後,用本地的私鑰M對APP進行簽名,同時把從蘋果服務器得到的Provisioning Profile文件打包進APP中,文件名爲embedded.mobileprovision,把APP安裝到iOS設備後,系統進行驗證。

查看資源文件簽名

查看APP的包內容,裏面會有_CodeSignature文件夾(裏面的就是資源文件的簽名),還有個可執行文件,可以用MachO查看,裏面的Code signature就是應用簽名。

該文章爲記錄本人的學習路程,希望能夠幫助大家,也歡迎大家點贊留言交流!!!文章地址:https://www.jianshu.com/p/4307de384a50

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章