-
背景
iOS軟件的開發和發布離不開證書和配置文件,如果要想發布app到Apple Store或者使用蘋果的推送通知功能,都需要個人開發者證書簽名該app,以便通過蘋果的認證和審核。由於我們公司的app不是單獨一個,而是一個客戶對應一個app,在新版本中,需要用到推送通知功能,就需要發布app到Apple Store,通過認證后才能正常使用蘋果提供的這個服務,同時,為了滿足部分客戶要把自己的app發布到Apple Store 的需求,因此,我們需要使用這部分功能的客戶上傳他們的個人開發者證書和相關文件。 這時,就需要對這些證書進行驗證和管理,以及在打包時,動態導入這個證書並簽名,這篇文章主要是為了記錄相關的原理、驗證證書、打包等技術點的實現細節。
-
專業詞匯
-
簽名證書:
簽名證書是用來在編譯代碼后進行代碼簽名的,主要是為了說明這個代碼的所有者和合法性。通過iOS7 的SDK編譯時,在編譯的時候就需要指定簽名證書,當然我們仍然可以在編譯后進行重簽名。
-
推送證書:
推送證書主要我們的服務器發送推送信息給蘋果服務器時,需要用到的認證證書,打包的時候不需要用到,僅僅是我們后台與蘋果服務器通訊時需要。
-
AppId:
每個應用都有唯一的AppId,全球唯一,是應用的一個標識。推送證書在生成時會要求指定AppId,因此一個推送證書對應唯一的AppId。
-
配置文件:
配置文件包含了以上幾乎所有的信息,包括這個應用的AppId,應用對應的簽名證書,應用是否開啟了推送功能,應用是開發版本還是發布版本,應用能夠被哪台手機安裝(對於發布版本的應用,是所有手機都可以安裝的)。
驗證、獲取證書的信息
-
簽名證書:后綴主要為 .p12,同時需要用戶輸入導入該證書的密碼
在這個簽名證書里面,可以獲得UID、證書名稱、證書有效期。在linux或mac下,使用openssl 來獲取相關的信息,命令如下:
(1) openssl pkcs12 -in ~/cert.p12 -nodes -passin pass:"my password" | openssl x509 -noout –text
可以輸出所有我們需要的信息,但是需要進行檢索和解析。(2) openssl pkcs12 -in ~/cert.p12 -nodes -passin pass:"my password" | openssl x509 -noout –dates
可以輸出證書的有效期(3) openssl pkcs12 -in ~/cert.p12 -nodes -passin pass:"my password" | openssl x509 -noout –subject
可以輸出證書的UID和證書名稱 -
推送證書(可選):后綴主要為 .p12,同時需要用戶輸入該證書的密碼 在這個簽名證書里面,同樣可以獲得UID、證書名稱、證書有效期、以及是否是推送通知類型的證書。命令同上。 如何判斷此 .p12文件是推送證書???下圖高亮處,后面跟着AppId
-
配置文件:后綴為 .mobileprovision
從這個配置文件中可以獲得AppId、有效期、證書類型,是開發版本還是發布版本等等。方法如下:
(1) 先把這個配置文件轉成xml,再解析,命令:
openssl smime -inform der -verify -noverify -in file.mobileprovision。
(2) xml節點說明:
配置文件生成的日期
<key>ExpirationDate</key>
<date>2014-10-28T03:19:05Z</date>
配置文件過期的時間
<key>application-identifier</key>
<string>KZV5N634G4.com.mdby.motan2.testForPush</string>
應用標識符,全球唯一,紅色部分需要在打包時傳給打包程序
就是,我所說的AppId
<key>aps-environment</key>
<string>development</string>
<key>aps-environment</key>
<string>production</string>
判斷該證書是發布版本,還是開發版本,當然,我們可以通過其他的標志來判斷。
<key>UUID</key>
<string>855C845A-2E51-414F-A29B-837AD1A67F67</string>
是一個唯一標識符,我們要想在工程中使用這個配置文件,一般是雙擊,然后在xcode 的工程中,就可以選擇這個配置文件了,其實那是系統解析了這個mobileprovision文件,提取里面的UUID,用這個UUID重新命名這個mobileprovision文件,然后將這個文件放到Mac 系統的~/Library/MobileDevice/Provisioning Profiles/這個目錄下。在Xcode 的工程中,就是默認在這個路徑下尋找可用的mobileprovision文件。因此我們編譯和打包前,需要通過這個UUID重新命名服務器端傳過來的mobileprovision文件,並放到上面那個目錄下,從而在打包命令中直接通過UUID指定配置文件。
推送證書制作
實際上,客戶所上傳的那個.p12后綴的推送證書,並不能直接用來推送信息,需要把里面的證書和私鑰同時提取到一個 .pem后綴的文件中,利用這個文件與Apple 服務器端通信。步驟如下:
-
p12文件中提取證書
openssl pkcs12 -in mykeystore.p12 -clcerts -nokeys -out mycert.pem -passin pass:"mdby2013"
-
p12文件中提取私鑰
openssl pkcs12 -nocerts -out mykey.pem -in push.p12 -passin pass:"mdby2013" -passout pass:"mdby2013"
-
合並cert和key
cat PushChatCert.pem PushChatKey.pem > ck.pem
編譯、簽名、打包
0、在低版本的command line 工具中,需要導入一個參數
export CODESIGN_ALLOCATE="/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/codesign_allocate"
1、解鎖Mac的鑰匙串
security unlock-keychain -p $1 "~/Library/Keychains/login.keychain"
$1是登錄系統鑰匙串的密碼
2、導入簽名證書到Mac的鑰匙串
security import /Users/mrghappy/app/mdby.p12 -k ~/Library/Keychains/login.keychain -P "$2" –A
$2是導入證書的密碼,這個是客戶在導出他們的簽名證書時,填寫的密碼 -A 表示這個證書對任意應用可用,有安全風險,需要謹慎,加上這個是為了不要每次打包使用該證書簽名時,總是彈出警告框,要求輸入密碼。
3、查看鑰匙串中是否有該導入的證書
security find-certificate -a -c "$2" -Z | grep ^SHA-1
$2 是證書的名稱,該命令會列舉出具有這個名稱的系統內的證書。
4、clean項目
xcodebuild clean
5、build項目
xcodebuild-target motan -configuration Release build PLATFORM_NAME=iphoneos BUILDSDK=/Developer-SDK7
CODE_SIGN_IDENTITY="$2"
PROVISIONING_PROFILE="$3"
其中$2變量是簽名證書對應的證書名稱。$3是配置文件對應的UUID
6、簽名、打包
xcrun -sdk iphoneos PackageApplication -v /Users/mrghappy/app/build/Release-iphoneos/$4.app -o /Users/mrghappy/app/build/Release-iphoneos/$4.ipa --sign "$2" --embed /Users/mrghappy/app/mdby.mobileprovision
其中$4是這個項目的名稱,--sign是指定簽名證書簽名,--embed 是打包時把配置文件打包進去。
7、當然,我們可以驗證一下打包好的ipa文件是否正確
codesign -d -vvv --file-list - /Users/mrghappy/app/build/Release-iphoneos/$4.app
8、為了防止鑰匙串中導入的證書過多,維護困難,我們可以在打包完后,刪除掉
security delete-certificate -c "$2" ~/Library/Keychains/login.keychain