iOS App 簽名原理

筆者接觸打包已經一段時間了,但一直對簽名都是似懂非懂,最近從加密數論知識起回看這部分知識,感覺還是有很多不懂的地方。先簡單說明一哈數學原理,然后說RSA 算法密鑰生成的步驟,最后回到 iOS 簽名打包,以及分享一哈利用重簽名做過的壞事(以學習、省時間為目的)。

非對稱加密

對稱加密是通過同一份密鑰加密和解密數據;而非對稱加密則有兩份密鑰,分別是公鑰和私鑰,用公鑰加密的數據,要用私鑰才能解密,用私鑰加密的數據,要用公鑰才能解密。

(1)乙方生成兩把密鑰(公鑰和私鑰)。公鑰是公開的,任何人都可以獲得,私鑰則是保密的。
(2)甲方獲取乙方的公鑰,然后用它對信息加密。
(3)乙方得到加密后的信息,用私鑰解密。

數學原理

數學原理太長(難)不看篇:有一條等式,三個數字可以關聯起來,從而達到互相驗證對方的數字是否配對。如果已知數字驗證等式很容易,但是如果未知這些數字,要推測出來對方的數字目前的技術還十分艱難。

互質的簡單結論

關于互質關系,我們不難得出以下結論:

  1. 任意兩個質數互質。
  2. 一個數是質數,另一個數只要不是它的倍數,兩數互質。
  3. 一個質數與比它小的數,兩數互質。
  4. 1 和任意自然數互質。
  5. p 是大于1的整數,p 和 p - 1互質。
  6. p 是大于1的奇數,p 和 p - 2互質。

歐拉函數

思考下面這個問題。

任意給定正整數n,請問在小于等于n的正整數之中,有多少個與n構成互質關系?

計算這個值的方法就叫做歐拉函數 ,以φ(n) 表示。? 如果n = 1,則φ(1) = 1 。? 如果n是質數,則 φ(n)=n-1 。由以上結論(3)得出。? 如果 n = pk (p為質數,k為大于等于1的整數),那么

image

因為 n 的因數只有 1、p、n,所以只要一個數因數分解不包含質數 p,才可能與 n 互質。而比p小,包含質數 p 的數有 1 p、2 * p、3 * p、...、pk-1×p,共有 pk-1 個。減去即可。比如 φ(8) = φ(23) =23 - 22 = 8 -4 = 4。? 如果 n 可以分解成兩個互質 的整數之積。? n = p1 * p2網上有種證明是“中國剩余定理”,看不懂??。。。說說自己的理解。比如 35 = 5 * 7。由于35 的因數只有1、5、7、35。對于比35小的數來說,有7個5的倍數,5個7的倍數,則有12個,由于35是重復計算的,則有11個。所以結果是 35 - 24 = 11。*φ(n) = p1 * p2 - p1 - p2 + 1 = (p1 - 1)(p2 -1) = φ(p1)φ(p2) **? 因為任意大于1的正整數,都可以由一系列質數相乘所得。

image

根據第四條,注意是要互質的數 ,可得
image

再根據第三條,可得
image

image

這就是歐拉函數 。

歐拉定理

歐拉定理是RSA算法的核心。理解了這個定理,就可能可以理解RSA。直接給結論。感興趣的可以自己去看證明(我也想看懂,但懵懵懂懂)。
image
image

即 a的φ(n)次方被n除的余數為1。
這個定理結合取余分配率可以用來簡化冪的模運算。

(ab)%c=(a%cb%c)%c

image

費馬小定理假設正整數 a 與質數 p 互質,n = p的情況下,由結論(3)可得:

image

image

模反元素

如果 a 和 n 互質,那么一定可以找到整數 b,使得 ab - 1 被 n 整除。這時,b 就叫做 a 的“模反元素”。不難發現,如果b是模反元素,那么b + a、b - a也是模反元素,模反元素不止一個 。
image

歐拉定理可以用來證明模反元素必然存在。
image

密鑰生成的步驟

假設龍神要與那個ta 進行加密通信,他要怎么做才能瞞過八卦的群眾呢?第一步,隨機選擇兩個不相等的質數 。龍神的幸運數字是61 那個ta 的幸運數字是53。第二步,相乘。

n = 61 * 53 = 3233

寫成二進制是 110010100001,一共有12位,所以這個密鑰是12位。(通常1024位,更安全的場合2048位)。第三步,計算n的歐拉函數φ(n)。

φ(n) = (p-1)(q-1),φ(3233) = 3120。

第四步,隨機選擇一個整數e,條件是1< e < φ(n),且e與φ(n) 互質。龍神選了17。第五步,計算e對于φ(n) 的模反元素d。

ed ≡ 1 (mod φ(n))

等價于

ed - 1 = kφ(n)
ex + φ(n)y = 1

17x + 3120y = 1

龍神算出一組整數解為(2753,-15),即 d = 2753。第六步,將 n 和 e 封裝成公鑰,n 和 d 封裝成私鑰。所以公鑰(3233,17),私鑰(3233,2753)。第七步, RSA 的可靠性。回顧上面的步驟,一共出現了六個數字。

p = 61
q = 53
n = p * q = 3233
φ(n) = (p-1)(q-1) = 3120
e = 17
d = 2753

我們上面提過,公鑰是公開的,所以 n 和 e 都是所有人能知道的。關鍵是d,如果泄漏了,就等于私鑰泄漏。那么,在已知 n 和 e 的情況下,怎么推導出 d?

(1) ed≡1 (mod φ(n))。只有知道e和φ(n),才能算出d。
(2) φ(n)=(p-1)(q-1)。只有知道p和q,才能算出φ(n)。
(3) n=pq。只有將n因數分解,才能算出p和q。

所以,只要因數分解n,就可以得到d。但是,對于一個很大的質數,要因數分解是非常困難的事 。所以,以目前的技術來看, RSA 是可靠的 。

加密和解密

公鑰:e 和 n
私鑰:d 和 n
明文:m
密文:c

公鑰和私鑰通過一條等式能互相驗證。有興趣的可以自己研究。RSA算法原理(二)[1]

image

image

加密假設龍神想說的悄悄話m,他就要用公鑰(3233,17)進行一次加密。這里必須注意,m是小于n的整數。然后算出下面式的c:

me ≡ c (mod n)

假設龍神說的悄悄話是 65,算出c 為2790。我們要用到歐拉定理

6517 mod 3233 = 2790

所以龍神就把2790發給那個ta。解密那個ta 收到2790后,就用私鑰(3233,2753)進行解密。

cd ≡ m (mod n)2790 ^ 2753 ≡ 65 (mod 3233)

所以原文就是65。RSA 的優缺點優點:目前來說安全。缺點:? 速度慢? 只適合加密小數據簡單介紹完一番我沒完全理解的數學理論后,下面進入簽名環節。

數字簽名

作用

數字簽名的作用是利用非對稱加密方法,自己持有私鑰,公布公鑰。互相加密以及驗證消息來源。

步驟

  1. 首先用一種算法,算出原始數據的摘要。需滿足
    a. 若原始數據有任何變化,計算出來的摘要值都會變化。
    b. 摘要要夠短。這里最常用的算法是MD5 。
    </pre>

  2. 生成一份非對稱加密的公鑰和私鑰,私鑰保留,公鑰公布出去。

  3. 對一份數據,算出摘要 后,用私鑰加密 這個摘要,得到一份加密后的數據,稱為原始數據的簽名。把它跟原始數據一起發送給用戶。

  4. 用戶收到數據和簽名后,用公鑰解密得到摘要。同時用同樣的算法計算原始數據的摘要,對比這里計算出來的摘要和用公鑰解密簽名得到的摘要是否相等,若相等則表示這份數據中途沒有被篡改過,因為如果篡改過,摘要會變化 。


    image

最簡單的簽名

image

iOS 設備用公鑰驗證一遍就知道該 App 是不是經過蘋果后臺認證的。如果被篡改過,肯定是不行的。然而,App 除了從 AppStore 下載,還有三種方式安裝:

  1. 開發 App 時可以直接把開發中的應用安裝進手機進行調試。
  2. In-House 企業內部分發,可以直接安裝企業證書簽名后的 APP。
  3. AD-Hoc 相當于企業分發的限制版,限制安裝設備數量,較少用。所以蘋果的簽名還有額外的事情要做。

蘋果的 App 簽名

我們來考慮上面第一種情況。首先,它既要有能不經蘋果私鑰驗證,馬上安裝的便利,又要經過蘋果驗證。聽起來有點繞。蘋果采用的方案是雙層簽名。
image
  1. 在 Mac 生成一對公私鑰,這里稱為公鑰L,私鑰L。
  2. 蘋果自己有固定的一對公私鑰,私鑰在蘋果后臺,公鑰在每個 iOS 設備上。
  3. 把公鑰 L 傳到蘋果后臺,用蘋果后臺里的私鑰 A 去簽名公鑰 L。得到一份數據包含了公鑰 L 以及其簽名,把這份數據稱為證書 。
  4. 在開發時,編譯完一個 APP 后,用本地的私鑰 L 對這個 APP 進行簽名,同時把第三步得到的證書一起打包進 APP 里,安裝到手機上。
  5. 在安裝時,iOS 系統取得證書,通過系統內置的公鑰 A,去驗證證書的數字簽名是否正確。
  6. 驗證證書后確保了公鑰 L 是蘋果認證過的,再用公鑰 L 去驗證 APP 的簽名,這里就間接驗證了這個 APP 安裝行為是否經過蘋果官方允許。(這里只驗證安裝行為,不驗證APP 是否被改動,因為開發階段 APP 內容總是不斷變化的,蘋果不需要管。)除了要保證經過驗證外,蘋果還要防止濫用這種途徑下載。想象一下,把真機連到 Mac 上,不就能想裝多少裝多少 App 嗎?那多部設備連到 Mac 上,App 不就能想裝在哪裝在哪嗎?蘋果的方案是識別 設備和 App。
    想調試的設備必須要到開發者網站申請,并且設備數量是有限制的。
    然后還針對每個Bundle Identifier(App ID)配不同的證書。
    這兩種數據都在上面第三步一起組成證書(暫且這么認為)。
    至此,證書就能實現 經過蘋果認證,并且能限制安裝設備數量和 App ID 。
    當然,證書不止有這些信息,還有推送等權限,蘋果把這些權限開關統一稱為Entitlements 。如果App 一開始的證書沒申請推送權限,那么后面新增權限后,需要更新配置。實際上,一個“證書”有規定的格式規范,不應把這些額外的信息往里塞。****所以上面的暫且這么認為部分是不對的。所以蘋果把證書和額外信息包裝起來 ,把它叫做 Provisioning Profile 。所以能拓展整個流程圖如下。
    image
  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 步下載回來的證書(存著公鑰),在本地找到對應的私鑰(第一步生成的),用本地私鑰去簽名 App,并把 Provisioning Profile 文件命名為 embedded.mobileprovision 一起打包進去。這里對 App 的簽名數據保存分兩部分,Mach-O 可執行文件會把簽名直接寫入這個文件里,其他資源文件則會保存在 _CodeSignature 目錄下。
  6. 第 6 – 7 步的打包和驗證都是 Xcode 和 iOS 系統自動做的事。
    ? CSR:Certificate Singing Request,證書簽名請求文件。包含電腦的公鑰信息。所以創建時不需要填任何和發布等有關的信息。
    ? Certificates證書:發布者證書。Apple Develop的ID 對某部電腦的授權證書。內容是公鑰或私鑰,由其他機構對其簽名組成的數據包。
    電腦擁有這個證書后,有權對該Apple Developer的ID下所有App進行真機測試、打包、發布。注意這里,并未指定App,換句話說,和App無關。
    ? CSR 和 Certificates 的聯系上面提到了Certificates包含了電腦的信息,這個信息來自于CSR。所以在創建Certificates時,需要提交CSR。相當于 Mac 的公鑰被蘋果私鑰 加密的過程。
    ? p12: 本地私鑰,可以導入到其他電腦。上面提到,擁有證書才有權做那些事。如果另一部電腦想發布,也需要證書。如果又創建一個新證書也能解決,但一般一個開發者帳號創建一個發布證書就夠了,而且蘋果對這證書數量有限制。這時候導出p12文件,相當于拷貝了一份私鑰。給另一部電腦安裝后,另一部電腦就有權了。
    ? Entitlements:包含了 App 權限開關等信息。
    ? Provisioning Profile: 描述文件。包含了證書、App ID、設備、Entitlements 等數據,并由后臺私鑰簽名的數據包。也稱為PP文件,.mobileprovision后綴文件。

小結

CSR文件包含本地公鑰,被蘋果私鑰加密后生成 Cer 證書。該證書與權限、App ID、設備等數據經蘋果私鑰加密后生成 PP文件。裝到真機時,會對 PP文件整體進行驗證,還會對 PP 文件中的 Cer 證書進行驗證。

蘋果的 App 驗證

上面說了開發包的驗證流程 。實際上 App 安裝以及每次啟動都會驗證。

各種證書的有效期

企業帳號發布證書有效期是3年,而開發證書有效期為1年,而描述文件開發發布都是只有1年有效期。個人帳號開發證書發布證書有效期都是1年,描述文件也全是1年有效期。下面再說說企業包 和 AD - Hoc以及 App Store的驗證流程。

企業包和 AD - Hoc包驗證流程

企業包和 AD -Hoc 的區別在于企業包不會限制安裝設備數量,并且需要信任證書。
因為這兩種包不經過 App Store,對App的簽名是用證書簽名的。所以證書經蘋果發布后,蘋果還想要限制的話,就必須檢查證書是否過期。這個步驟被放到了啟動 App 時。因此,如果證書過期或者 revoke掉,開發者賬號被封禁,都會導致 App 啟動時閃退。

  1. 證書過期或 revoke? app 會馬上不能使用,并且由于 PP 文件包含它,也會失效。
  2. PP 文件過期 或 revoke? 也會閃退,但可能不會馬上反應過來,可能由于網絡原因等,不能馬上驗證失效。
  3. 賬號被注銷? 閃退

App Store 的驗證流程

blog.cnbang.net/wp-content/…
image

其實就是最簡單的驗證流程。我們上傳 App 到 App Store時驗證我們的證書、PP文件。從此,與我們的文件再無關系。上傳后,蘋果在后臺直接用私鑰簽名 App 就可以了。如果去下載一個 AppStore 的安裝包,會發現它里面是沒有 embedded.mobileprovision 文件的,也就是它安裝和啟動的流程是不依賴這個文件,驗證流程也就跟上述幾種類型不一樣了。已經在蘋果商店下載安裝的app不受影響(無論是過期還是Revoke,甚至是開發者賬號被注銷,因為這個時候,對于app的簽名,是通過蘋果私鑰直接簽名的,沒有使用開發者名下的私鑰簽名)。但App Store 會下架相關的 App。筆者之前遇到一個場景就是,違規操作被注銷是沒辦法的(注意保護開發者賬號,可以開啟雙重驗證,不要被偷去做馬甲包然后被舉報了)。那么對于企業包證書過期問題怎么處理呢?因為有效期為1年,我們可以申請兩個 PP 文件,相隔半年,差不多到時間發新版時就換個新 PP 文件。更多可以看iOS 各種證書的作用、有效期、過期的后果和解決辦法[2]

重簽名

正常的打包流程就不再說了。iOS完整的證書申請和打包過程[3]對 ipa 包進行修改后,由于摘要變了,所以驗證會不通過。我們可以采用重簽名達到驗證的效果。常用于逆向別人的 App,微信多開等途徑。

App 的大致結構

打包出來 ipa 后,我們解壓可以看到大致結構。
image

? 資源文件:例如圖片、html等等? CodeSignature/CodeResources:這是一個 plist 文件,可用文本查看,其中的內容就是程序包(不包括Frameworks)所有文件的簽名。意味著你的程序一旦簽名,就不能更改其中任何文件。? 可執行文件:此文件跟資源文件一樣需要簽名。? mobileprovision:校驗證書文件、Bundle ID。? Frameworks:程序引用的系統自帶的Frameworks,每個Frameworks其實就是一個 app,也包含簽名信息。

iOS 系統驗證簽名有效性的過程

  1. 解壓ipa2) 取出 embedded.mobileprovision,校驗是否被篡改過3) 校驗所有文件的簽名4) 驗證設備是否符合embedded.mobileprovision 的信息5) 對比 Info.plist 的 Bundle Id 是否符合 embedded.mobileprovision 文件中的信息

重簽名的原理

既然簽名是由證書和mobileprovision共同實現,那么重簽名的過程其實就是將新的證書和mobileprovision替換舊文件的過程,但由于系統在驗證app是否合法的時候還會隨機驗證授權設備列表和Bundle ID、所以必須修改Bundle ID與新的mobileprovision中的信息保持一致,否則將會有驗證失敗的風險。

重簽名的嘗試

筆者之前打的是企業包,針對不同客戶要實現不同 App Icon 和 App name等。如果一個一個打,一個打7分鐘。??利用重簽名,可以快速替換 ipa 中的內容,實現裝逼的效果。步驟如下1) 打包出一份 ipa。2) 修改 ipa 內對應文件。此時摘要變化了,相當于簽名失效,蘋果校驗時就知道該 app 被篡改 了。3) 重簽名? 3.1 刪除插件
? 3.2 對FrameWorks進行簽名
? 3.3 給可執行文件執行權限
? 3.4 拷貝描述文件
? 3.5 修改info.plist中的Bundle ID
? 3.6 生成plist權限文件
? 3.7 簽名整個APP
? 3.8 生成ipa包具體實現,更多可查看之前寫過的一篇文章 iOS —— 兩套自動打包腳本[3]

參考

[1]http://www.ruanyifeng.com/blog/2013/07/rsa_algorithm_part_two.html
[2]http://www.lxweimin.com/p/95ca850e7ece
[3]https://juejin.im/post/5be2e07fe51d454d5c7c2b9

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,401評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,011評論 3 413
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,263評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,543評論 1 307
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,323評論 6 404
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,874評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 42,968評論 3 439
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,095評論 0 286
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,605評論 1 331
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,551評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,720評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,242評論 5 355
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 43,961評論 3 345
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,358評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,612評論 1 280
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,330評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,690評論 2 370

推薦閱讀更多精彩內容