本文轉載自
鏈接 http://blog.csdn.net/close_marty/article/details/38441903
作者 close_marty
最近設計的同事找到我,說有沒有什么方法可以很方便的獲取和安裝我們應用最新的測試包,然后還給我看了別人通過微信朋友圈分享測試包的做法。好吧,雖然我手頭沒有外網服務器,那我就在內網搭一個吧,然后先在內網實現通過wifi直接安裝測試包。
首先大概說下OTA吧,OTA就是over the air,是一種無線發布方式,它可以實現app的在線安裝,不再需要數據線。目前國內有不少團隊通過使用企業證書+OTA的方式來發布自己的應用,所以你會看到有的網頁上有某個應用的廣告,你點擊之后就直接提示你是否安裝這個app,一旦你確定,它就直接在你的手機上安裝了,這中間完全沒有經過appstore的參與和審核。這也是實現在不越獄的手機上安裝未經審核app的方法。不過我們自己的測試包都是使用開發者證書來打包的,所以只有指定的設備才可以安裝。
要實現OTA,需要準備下面這三個文件,然后把他們放到自己的web服務器上,通過訪問你的web頁面來實現在線安裝。
*.ipa文件,也就是你的安裝包,可以是開發者證書簽名的,也可以是企業證書,看你的用途和目的
*.plist文件,這個描述文件主要是用來說明應用的安裝信息的,下面一個簡單的sample
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>items</key>
<array>
<dict>
<key>assets</key>
<array>
<dict>
<key>kind</key>
<string>software-package</string>
<key>url</key>
<string>http://${YOUR_DOMAIN_DOTCOM}/${PATH_TO_BETA_IF_ANY}/${APPLICATION_NAME}.ipa</string>
</dict>
</array>
<key>metadata</key>
<dict>
<key>bundle-identifier</key>
<string>${BUNDLE_IDENTIFIER}</string>
<key>bundle-version</key>
<string>${APPLICATION_VERSION}</string>
<key>kind</key>
<string>software</string>
<key>title</key>
<string>${DISPLAY_NAME}</string>
</dict>
</dict>
</array>
</dict>
</plist>
其中指定了ipa文件的具體存放路徑。這個plist可以在打包的過程中自動生成,具體方法可以參考這里,我不再贅述
http://aaronparecki.com/articles/2011/01/21/1/how-to-distribute-your-iOS-apps-over-the-air
也可以通過正常流程打包完ipa包之后,根據ipa文件來生成plist文件,可參考第三方的工具
https://github.com/sveinungkb/ios-ota-buddy
還可以自己手動去編寫這么一個文件或者自己寫個腳本去生成,只要包含這些主要信息即可。
- 一個或簡單或復雜的發布頁面,目的是提供一個itms-services協議的鏈接,讓用戶訪問這個鏈接即可實現在線安裝。一個最簡單的html頁面就是下面這樣。
<a href="itms-services://?action=download-manifest&url=https://xxx.xxx.xxx/xxx.plist">Install App</a>
整個OTA的核心就是蘋果的itms-services協議, safari通過解析類似于itms-services://?action=download-manifest&url=https://xxx.xxx.xxx/xxxx.plist 這樣的一個鏈接來實現在線安裝。url就是你的*.plist文件所在的地址,在iOS7.1以前,這個url是沒有限制的,在7.1之后,蘋果做了修改,要求這個url必須是可信任的https鏈接。其他地方的鏈接并沒有要求。
對于https鏈接,目前主流的有三種解決方案。
方案1:交給公司解決,讓公司提供一個可信的https連接,這個最直接。
方案2:采用第三方的網站提供的https連接,比較常見的就是把plist上傳到dropbox,然后分享出去,它的外鏈就是https的(不過dropbox已經被墻了,so...),國內網盤的外鏈貌似都是http的,基本可以忽略
方案3:使用自建的https連接
我們是個小團隊,采用的方案3,但是這里有個問題,https是需要有證書的,而可信的證書必須是由知名的CA所頒發,當然,向這些知名的CA申請證書是需要money的。由于我使用OTA的目的只是在團隊內部分發一下測試包而已,所以我們采用自簽名的證書來加密https。
自簽名分為兩個步驟,首先生成自己的CA根證書,再用這個根證書去簽名我們服務器所使用的證書。
- 生成自己的根證書
生成自己的密鑰對
openssl genrsa -out ca.key 1024
生成證書請求文件,并使剛剛的key來加密CA根證書
openssl req -new -x509 -days 365 -key ca.key -out ca.crt
其中-x509選項表示生成自簽名的證書,生成證書會要求填一系列的東西,此時可以任意填寫,也可以直接回車,Common Name (e.g. server FQDN or YOUR name) []:,這一項建議填寫一個便于識別的名字,比如可以是你的名字或者代號。
完成到這里你就已經生成了自己的根證書了,你也和那些知名CA機構一樣,用根證書給別人的證書簽名啦。。撒花。。。不過由于你不知名,沒有人會認可你的證書,所以你簽名的所有證書都是不會被信任的。
- 生成服務器使用的證書,并用自己的根證書簽名
步驟基本同上:
生成一個密鑰對
openssl genrsa -out server.key 1024
生成證書請求文件
openssl req -new -key server.key -out server.csr
這里又需要填寫之前的那一堆東西,值得注意的是,
Common Name (e.g. server FQDN or YOUR name) []:
這里一定要填寫你的https連接所對應的域名或者是服務器Ip, 比如xxx.xxx.com或者是192.168.25.68這樣。
接下來我們需要使用根證書對這個證書進行簽名,但是在簽名之前,需要做一些準備工作, 我們需要構建這樣一個目錄結構,在當前目錄新建文件夾demoCA,
進入demoCA,在demoCA下創建兩個文件index.txt和serial ,以及文件夾newcerts,其中index.txt的內容為空,serial的內容為01。
完成之后,就可以開始簽名了
openssl ca -in server.csr -out server.crt -cert ca.crt -keyfile ca.key
openssl ca -in server.csr -out server.crt -cert ca.crt -keyfile ca.key
這條命令中涉及的所有文件都是在之前步驟中生成的,如果缺少了什么文件,最好回去檢查一下步驟是否有問題。
命令執行后會要求確認是否進行簽名,確認即可。
到這里,證書的構造已經完成,最終的目錄結構應該是這個樣子
- 讓iOS設備信任你的根證書
之前說過了,自簽名的證書是不可信的,所以你需要讓通過OTA方式來安裝app的手機去信任你的證書。
方式1:把你的根證書文件,也就是ca.crt 放到web服務器的某個位置,然后iOS設備通過safari去訪問這個文件就會直接提示用戶安裝證書,點擊安裝即可。(只能是safari,不能是其他瀏覽器)
方式2:通過email方式,把ca.crt作為附件通過郵件發送到iOS設備上,然后也可以打開安裝
方式3:其他我不知道的方式,比如什么iPhone配置實用工具之類的,總之呢,就是讓iOS設備去打開并安裝ca.crt這個文件。
我采用的方式1,我把ca.crt的url和itms-services鏈接一起放在一個簡單的發布頁面install.html里面的,然后把html的地址生成個了一個二維碼,發給大家。其他人掃描二維碼,訪問這個頁面,然后點擊兩下,第一下安裝證書,第二下安裝app,就可以搞定了。
安裝之后,這個證書文件就會變為可信的了。可以在iOS設備上的通用-描述文件中查看這個證書的狀態。
- 修改itms-services協議中的url為https
比如itms-services://?action=download-manifest&url=https://172.16.8.53/OTA-Install/xxxxxxx..plist,當然如果已經是https的,那就不用改了。
至于ipa文件是否使用https并不重要,蘋果只要求itms-services協議中的url字段使?用https。
至此就可以在iOS7.1及以上的設備中通過OTA方式安裝了。
附1:
前面的 openssl req 和 openssl ca 命令,有可能需要增加一個config參數
-config ..\conf\openssl.cnf
不過我沒有加,所以默認使用的
Using configuration from /System/Library/OpenSSL/openssl.cnf
附2:Apache服務器的openssl配置(mac OSX 環境)
- 確保 httpd.conf 中 LoadModule ssl_module 這項設置是有效的
- 在 httpd-ssl.conf 中,確保下?面的配置有效,并且對應的crt和key文件正確(這兩個文件就是我們之前自己生成的服務器使用的證書和密鑰)
SSLCertificateFile "/private/etc/apache2/ssl/server.crt"
SSLCertificateKeyFile "/private/etc/apache2/ssl/server.key" - 記得重啟服務器
- 檢查https是否生效可以訪問 https:localhost