ios APP 簽名

來源:互聯網
上載者:User

標籤:www.   規範   下載   公開金鑰   不用   標記   相等   先來   icloud   

前言

相信很多同學對於iOS的真機調試,App的打包發布等過程中的各種認證、Provisioning Profile、 CertificateSigningRequestp12的概念是模糊的,導致在實際操作過程中也很容易出錯。好在Xcode8.0出現了Automatically manage signing,讓我們在這步操作中減少了難度。雖然說我們在Xcode8.0之後可以選擇讓Xcode自動管理了,但是我們還是應該知道App簽名的原理。本文嘗試從原理出發,一步步推出為什麼會有這麼多概念,希望能有助於理解iOS App簽名的原理和流程。

簽名目的

先來看看蘋果採用簽名機制的目的。在iOS出來之前,在主流作業系統(Mac/Windows/Linux)上開發和運行軟體是不需要簽名的,軟體隨便從哪裡下載都能運行,導致平台對第三方軟體難以控制,盜版流行。蘋果就希望在iOS平台對第三方App有絕對的控制權,一定要保證每一個安裝到iOS上的App都必須經過蘋果官方認證的。那麼問題來了,怎麼保證呢?就是通過簽名這種機制。

非對稱式加密

通常我們所說的簽名就是數位簽章,它是基於非對稱式加密演算法實現的。對稱式加密是通過同一份祕密金鑰加密和解密資料,而非對稱式加密則有兩份密鑰,分別是公開金鑰和私密金鑰,用公開金鑰加密的資料,要用私密金鑰才能解密;用私密金鑰加密的資料,要用公開金鑰才能解密。

簡單說一下常用的非對稱式加密演算法RSA的數學原理,理解簡單的數學原理,就可以理解非對稱式加密是怎麼做到的,為什麼是安全的:

1. 選兩個質數`p`和`q`,相乘得出一個大整數`n`,例如:p=61,q=53,n=p*q=32332. 選 1-`n` 間的隨便一個質數`e`,例如:e=173. 經過一系列數學公式,算出一個數字`d`,滿足:    a. 通過`n`和`e`這兩個資料進行數學運算後,可以通過`n`和`d`去反解運算,反過來也可以。    b. 如果只知道`n`和`e`,要推匯出`d`,需要知道`p`和`q`,也就是需要把`n`因數分解。    

上述的(n,e)這兩個資料在一起就是公開金鑰,(n,d)這兩個資料就是私密金鑰,滿足用公開金鑰加密,私密金鑰解密,或者反過來私密金鑰加密,公開金鑰解密;也滿足在只暴露公開金鑰(只知道ne)的情況下,要推匯出私密金鑰(n,d)需要把大整數n因數分解,目前因數分解只能靠暴力窮舉,而n數字越大,越難以用窮舉計算出因數pq,也就越安全,當n大到二進位1024位或2048位時,以目前技術要破解幾乎不可能,所以非常安全。

若對數字d是怎樣計算出來的感興趣,可以詳讀這兩篇文章:RSA 演算法原理(一)(二)

數位簽章

現在知道了有非對稱式加密演算法這東西,那麼數位簽章是怎麼回事呢?
數位簽章的作用是我對某一份資料打了個標記,表示我認可了這份資料(簽了個名),然後我發送給其他人,其他人可以知道這份資料是經過我認證的,資料沒有被篡改過。
有了上述非對稱式加密,就可以實現這個需求:

  1. 首先用一種演算法,算出未經處理資料的摘要,需要滿足:

    a. 若未經處理資料有任何變化,計算出來的摘要值也要有變化。

    b. 摘要要夠短,這裡常用的演算法是MD5

  2. 產生一份非對稱式加密的公開金鑰和私密金鑰,私密金鑰自己拿著,公開金鑰發布出去。
  3. 對一份資料,算出摘要之後,用私密金鑰加密這個摘要,得到一份加密後的資料,稱為未經處理資料的簽名。把它跟未經處理資料一起發送給使用者。
  4. 使用者收到資料和簽名後,用公開金鑰解密得到摘要,同時使用者用同樣的演算法計算未經處理資料的摘要,比對這裡計算出來的摘要和公開金鑰解密簽名得到的摘要是否相等,若相等則表示這份資料中途沒有被篡改過,因為如果有篡改,摘要會變化。

之所以要有第一步計算摘要,是因為非對稱式加密的原理限制可加密的內容不能太大(不能大於上述n的位元,也就是一般不能大於1024位/2048位),於是若要對任意大的資料簽名,就需要改成對它的特徵值簽名,效果是一樣的。

好了,有了非對稱式加密和數位簽章的基礎之後,怎麼樣可以保證一份資料是經過某個地方認證的,來看看怎麼樣通過數位簽章的機制來保證每一個安裝到iOS的App都是經過蘋果認證允許的。

最簡單的簽名

要實現這個需求很簡單,最直接的方式,蘋果官方產生一對公私密金鑰,在iOS裡內建一個公開金鑰,私密金鑰由蘋果後台儲存,我們傳App上AppStore時,蘋果後台用私密金鑰對App資料進行簽名,iOS系統下載這個App後,用公開金鑰驗證這個簽名,若簽名正確,這個App肯定由蘋果後台認證的,並且沒有被修改過,也就達到了蘋果的需求:保證安裝的每一個App都是經過蘋果認證允許的。

如果我們iOS安裝App只有從AppStore下載一種方式的話,這樣就可以搞定了,沒有任何複雜的東西,只有一個數位簽章,非常簡單的解決問題。
但是實際上,因為安裝App除了從AppStore下載,我們還可以有三種方式安裝一個App:

  1. 開發App時可以直接把開發中的應用安裝進手機調試;
  2. In-House企業內部分發,可以直接安裝企業認證簽名後的App;
  3. AD-Hoc相當於企業分發的限制版,限制安裝裝置數量,較少用。

蘋果要對用這三種方式安裝的App進行控制,就有了新的需求,無法像上面這件簡單了。

新的需求

我們先來看第一個,開發時安裝App,它有兩個需求:

  1. 安裝包不需要傳到蘋果伺服器,可以直接安裝到手機上。如果你編譯一個App到手機前要先傳到蘋果伺服器簽名,這顯然是不能接受的。
  2. 蘋果必須對這裡的安裝有控制權,包括:

    a. 經過蘋果允許才可以這樣安裝;

    b. 不能被濫用導致非開發App也能這樣安裝;

為了實現這些需求,iOS簽名的複雜度也就開始增加了。
蘋果這裡給出的方案是使用了雙層簽名,會比較繞,流程大概是這樣的:

  1. 在你的Mac開發機器產生一對公私密金鑰,這裡稱公開金鑰L,私密金鑰L。(L:Local)
  2. 蘋果自己有固定的一對公私密金鑰,跟上面AppStore例子一樣,私密金鑰在蘋果後台,公開金鑰內建在每個iOS裝置上,這裡稱為公開金鑰A,私密金鑰A。(A:Apple)
  3. 把公開金鑰L上傳到蘋果後台,用蘋果後台裡的私密金鑰A去簽名公開金鑰L。得到一份資料包含了公開金鑰L以及其簽名,把這份資料稱為認證。
  4. 在開發時,編譯完一個App後,用本地的私密金鑰L對這個App進行簽名,同時把第三步得到的認證一起打包進App裡,安裝到手機。
  5. 在安裝時,iOS系統取得認證,通過系統內建的公開金鑰A,去驗證認證的數位簽章是否正確。
  6. 驗證認證確保公開金鑰L是蘋果認證過的,再用公開金鑰L去驗證App的簽名,這裡就間接驗證了這個App的安裝行為是否經過蘋果官方允許。(這裡只驗證安裝行為,不驗證App是否被改動,因為開發階段App內容總是不斷變化的,蘋果不需要管)。
加點東西

上述流程只解決了上面第一個需求,也就是需要經過蘋果允許才可以安裝,還未解決第二個避免被濫用的問題。怎麼解決呢?蘋果加了兩個限制,一是限制在蘋果後台註冊過的裝置才可以安裝;二是限制簽名只能針對某一個具體的App。
那麼它到底是怎麼添加這兩個限制的呢?在上述第三步,蘋果用私密金鑰A簽名我們的本地公開金鑰L時,實際上除了簽名本地公開金鑰L外,還可以加上無限多資料,這些資料都可以保證是經過蘋果官方認證的,不會有被篡改的可能。

可以想到把允許安裝的裝置ID列表和App對應的AppID等資料,都在第三步這裡跟公開金鑰L一起組成認證,再用蘋果私密金鑰A對這個認證簽名。在最後第5步驗證時就可以拿到裝置ID列表,判斷當前裝置是否符合要求。根據數位簽章的原理,只要數位簽章通過驗證,第5步這裡的裝置IDs/AppID/公開金鑰L就都是經過蘋果認證的,無法被修改,蘋果就可以限制可安裝的裝置和APP,避免濫用。

最終流程

到這裡這個認證已經變得很複雜了,有很多額外資訊,實際上除了裝置ID/AppID,還有其他資訊也需要在這裡用蘋果簽名,像App裡iCloudpush、後台運行 等許可權蘋果都想控制,蘋果把這些許可權開關統稱為Entitlements,它也需要通過簽名去授權。
實際上一個認證本來就有規定的格式規範,上面我們把各種額外的資訊塞入認證裡是不合適的,於是蘋果另外搞了一個東西,叫Provisioning Profile,一個Provisioning Profile裡就包含了認證以及上述提到的所有額外資訊,以及所有資訊的簽名。
所以,整個流程稍微變一下,就成這樣了:

因為步驟有小變動,這裡我們不辭囉嗦重新再列一遍整個流程:

  1. 在你的 Mac 開發機器產生一對公私密金鑰,這裡稱為公開金鑰L,私密金鑰L。L:Local
  2. 蘋果自己有固定的一對公私密金鑰,跟上面 AppStore 例子一樣,私密金鑰在蘋果後台,公開金鑰在每個iOS裝置上。這裡稱為公開金鑰A,私密金鑰A。A:Apple
  3. 把公開金鑰L傳到蘋果後台,用蘋果後台裡的私密金鑰A去簽名公開金鑰L。得到一份資料包含了公開金鑰L以及其簽名,把這份資料稱為認證。
  4. 在蘋果後台申請AppID,配置好裝置ID列表和APP可使用的許可權,再加上第③步的認證,組成的資料用私密金鑰A簽名,把資料和簽名一起組成一個Provisioning Profile檔案,下載到本地Mac開發機。
  5. 在開發時,編譯完一個APP後,用本地的私密金鑰L對這個APP進行簽名,同時把第④步得到的Provisioning Profile檔案打包進APP裡,檔案名稱為 embedded.mobileprovision,把APP安裝到手機上。
  6. 在安裝時,iOS系統取得認證,通過系統內建的公開金鑰A,去驗證 embedded.mobileprovision的數位簽章是否正確,裡面的認證簽名也會再驗一遍。
  7. 確保了embedded.mobileprovision裡的資料都是蘋果授權以後,就可以取出裡面的資料,做各種驗證,包括用公開金鑰L驗證APP簽名,驗證裝置ID是否在ID列表上,AppID是否對應得上,許可權開關是否跟APP裡的Entitlements對應等。

開發人員認證從簽名到認證最終蘋果採用的流程大致是這樣,還有一些細節像認證有效期間/認證類型等就不細說了。

概念和實際操作

上面的步驟對應到我們平常具體的操作和概念是這樣的:

  1. 第1步對應的是keychain裡的“從憑證授權單位請求認證”,這裡就本地產生了一對公私密金鑰,儲存的CertificateSigningRequest就是公開金鑰,私密金鑰儲存在本地電腦裡。
  2. 第2步蘋果自己處理,我們不用管。
  3. 第3步對應把CertificateSigningRequest傳到蘋果後台產生認證,並下載到本地。這時本地有兩個認證,一個是第1步產生的,一個是這裡下載回來的,keychain會把這兩個認證關聯起來,因為它們的公私密金鑰是對應的,在Xcode選擇下載回來的認證的時,實際上會找到keychain裡面對應的私密金鑰去簽名。這裡私密金鑰只有產生它的這台Mac才有,如果別的Mac也要編譯簽名這個App,怎麼辦?答案是把私密金鑰匯出給其他Mac使用,在keychain裡面匯出私密金鑰,就會存成.p12檔案,其他Mac開啟後就匯入私密金鑰。
  4. 第4步都是在蘋果網站上操作,配置AppID許可權裝置等,最後下載 Provisioning Profile檔案。
  5. 第5步Xcode會通過第3步下載回來的認證(存著本地公開金鑰),在本地找到對應的私密金鑰(第1步產生的),用本地私密金鑰去簽名App,並把Provisioning Profile檔案命名為embedded.mobileprovision一起打包進去。這裡對App的簽名資料儲存分為兩部分,Mach-O可執行檔會把簽名直接寫入這個檔案裡,其他資源檔則會儲存在_CodeSignature目錄下。
  6. 第6、7步的打包和驗證都是 Xcode 和 iOS 系統自動做的事。

這裡再總結一下這些概念:
認證:內容是公開金鑰或私密金鑰,由其他機構對其簽名組成的資料包。
Entitlements:包含了App許可權開關列表。
CertificateSigningRequest:本地公開金鑰。
.p12:本地私密金鑰,可以匯入到其他電腦。
Provisioning Profile:包含了 認證/Entitlements 等資料,並由蘋果後台私密金鑰簽名的資料包。

其他發布方式

前面以開發包為例子說了簽名和驗證的流程,另外兩種方式In-House企業簽名和AD-Hoc流程也是差不多的,只是企業簽名不限制安裝的裝置數,另外需要使用者在iOS系統設定上手動點擊信任這個企業才能通過驗證。
AppStore的簽名驗證方式有些不一樣,前面我們說到最簡單的簽名方式,蘋果在後台直接用私密金鑰簽名App就可以了,實際上蘋果確實是這樣做的,如果去下載一個AppStore的安裝包,會發現它裡面是沒有embedded.mobileprovision檔案的,也就是它安裝和啟動的流程是不依賴這個檔案,驗證流程也就跟上述幾種類型不一樣了。

據猜測,因為上傳到AppStore的包蘋果會重新對內容加密,原來的本地私密金鑰簽名就沒有用了,需要重新簽名,從AppStore下載的包蘋果也並不打算控制它的有效期間,不需要內建一個embedded.mobileprovision去做校正,直接在蘋果用背景私密金鑰重新簽名,iOS安裝時用本地公開金鑰驗證App簽名就可以了。

那為什麼發布AppStore的包還是要跟開發版一樣搞各種認證和Provisioning Profile?猜測因為蘋果想做統一管理,Provisioning Profile裡包含一些許可權控制,AppID 的檢驗等,蘋果不想在上傳AppStore 包時重新用另一種協議做一遍這些驗證,就不如統一把這部分放在 Provisioning Profile裡,上傳AppStore時只要用同樣的流程驗證這個 Provisioning Profile是否合法就可以了。

所以 App 上傳到AppStore後,就跟你的 認證 / Provisioning Profile 都沒有關係了,無論他們是否到期或被廢除,都不會影響AppStore 上的安裝包。

到這裡 iOS 簽名機制的原理和主流程大致說完了,希望能對理解蘋果簽名和排查日常簽名問題有所協助。

致謝

感謝各位能改耐心看完,也希望能夠對大家帶來協助。同時也感謝原作者的文章。本篇文章主要是為了做筆記。

最後,打一波廣告,需要簽名的朋友可以加QQ:2302398895 一朋友專業做ios APP簽名。

ios APP 簽名

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.