作者:Joe,原文鏈接,原文日期:2016-04-16
譯者:pucca601鹿鳖;校對:Cee;定稿:千葉知風(fēng)
密鑰壮莹,或者說「憑證」翅帜,是在使用 REST API 時難免會碰到的一件事情。當你注冊了 Amplitude 后命满,你會得到一個密鑰用來唯一識別你的應(yīng)用涝滴。若你使用的是 Aeris Weather 的 API,會得到一個 ID 和密碼周荐。如果你要在 iOS 應(yīng)用里調(diào)用這些 API狭莱,則需要把這些 API 密鑰放在某處。在之前的一篇文章中我們整理了如何在屬性列表文件中放置 API 密鑰概作。這篇教程中腋妙,我們將要加密這些 API 密鑰并且關(guān)注如何在你的 app 中訪問它們。
在我們開始之前讯榕,我想要談?wù)劙踩珕栴}骤素。我不是一個安全領(lǐng)域的專家,你很可能也不是愚屁。這篇文章原本的標題是「加密 API 密鑰」济竹,但經(jīng)過再三考慮,我重新將其命名為「混淆 API 密鑰」霎槐。文章中沒有一處對這種混淆方式不會被破解進行了保證送浊,因為任何人真的想要盜取你的 API 密鑰時一定會用各種手段獲取到∏鸬混淆這種方式只能為盜取提高一點門檻袭景。
加密你的密鑰
想要對我們的 API 密鑰另加一層保護,我們需要用到 Blowfish Cipher Feedback闭树。使用這種加密方式你需要選擇:
- 一串密鑰
- 一個初始化矩陣
密鑰至少有 8 個字符耸棒,至多 56 個字符。選擇任意你喜歡的密鑰:一個詞組报辱,亦或是混亂的字符与殃。初始化矩陣應(yīng)該是個隨意的 8 字節(jié)矩陣。選擇完密鑰和初始化矩陣后,下載我們的 Key Encrypter幅疼。輸入密鑰和初始化矩陣字符串米奸,以及你希望加密的 API 密鑰。例如衣屏,我們要加密的 API 密鑰是 6bbb3654679105f33cf8c491ed9b04df躏升,密鑰是 dontusethissecret辩棒,初始化矩陣是 decafbadbaddecaf狼忱。輸入后點擊 Encrypt。
點擊后的輸出結(jié)果是一串十六進制的字符串一睁,一起的钻弄,當然,還有最初的密鑰和初始化矩陣者吁。
解密你的密鑰
加密和解密的程序用了 Blowfish 的實現(xiàn)窘俺,源碼在 mbed TLS 上。程序用 C 語言實現(xiàn)复凳,在 Swift 中可以利用一個 bridging header 來使用這段程序瘤泪。
我們的解密方法在 Swift 中看起來像這樣:
func decrypt(message:[UInt8], key:String, iv:[UInt8]) -> String? {
var context:mbedtls_blowfish_context = mbedtls_blowfish_context()
let keybits = UInt32(key.characters.count*8)
// 初始化 Blowfish context 和設(shè)置 key
mbedtls_blowfish_init(&context)
mbedtls_blowfish_setkey(&context, key, keybits)
var decryptIV:[UInt8] = iv
var ivOffset = 0
var output:[UInt8] = [UInt8](count:message.count, repeatedValue:0)
if mbedtls_blowfish_crypt_cfb64(&context,
MBEDTLS_BLOWFISH_DECRYPT,
message.count,
&ivOffset,
&decryptIV,
message,
&output) == 0 {
return String(bytes: output, encoding: NSUTF8StringEncoding)
} else {
return nil
}
}
現(xiàn)在的問題是,在你的代碼中如何使用解密方法以及要將密鑰和初始化矩陣該放在何處育八。這取決于你(還有多種方法可以做到)对途。只要記住不管你做什么,如果有人決心要破解你的加密信息髓棋,他們一定能想盡各種辦法做到实檀。這只是當從一臺越獄的手機上解密和反編譯 app 后,他們需要另外攻破的一道防線按声。
為了測試我們對生成的字符串的解密方法膳犹,下載這個 iOS 例子,在 Xcode 里打開签则,然后運行须床。你需要對照一下原始的 API 密鑰 6bbb3654679105f33cf8c491ed9b04df。
獲取源代碼
Mac 上的加密應(yīng)用和解密 API 驗證序列的代碼可以在 Bitbucket 找到:
您可以自定義修改你的加密程序渐裂;Blowfish CFB 僅僅是眾多選項中的一種豺旬。
一些思考
老實說,發(fā)這篇文章我有些擔(dān)憂芯义。安全是一個吸引了很多注意力的話題哈垢,關(guān)注的開發(fā)者中有很多都有自己的態(tài)度。你會經(jīng)常聽到如下:
- 混淆方式不安全扛拨!
- 永遠不要寫你自己的加密程序耘分!
- 如果你不知道自己在做什么就不要做!
等諸如此類的說辭。盡管與此同時我們被告知要更有安全意識并且在編寫過程中保持這種意識求泰。用來訪問服務(wù)的 REST API 驗證序列提供給每日開發(fā)者央渣,而大多數(shù)文檔掩蓋了如何將其更安全地嵌入你的移動應(yīng)用中。
最后渴频,Dexguard 的安卓版作者在 Stack Overflow 上總結(jié)了一篇關(guān)于如何恰當?shù)卮鎯?API 密鑰的文章:
最終變成了經(jīng)濟學(xué)上的交易問題你必須做出選擇:你的密鑰有多重要芽丹,你能負擔(dān)多少時間,負擔(dān)多貴的軟件卜朗,對序號感興趣的黑客有多么復(fù)雜拔第,他們愿意花費多少時間,延遲黑客獲取密鑰有多少價值场钉,成功了的黑客多大程度會分發(fā)密鑰蚊俺,等等。類似密鑰這樣小的信息片段比整個應(yīng)用更難防護逛万。本質(zhì)上來說泳猬,在客戶端沒有什么是不能破解的,然而你還是可以設(shè)置障礙宇植。 – Eric LaFortune
當你要做出決策關(guān)于在你的移動應(yīng)用上實行什么樣的安全等級得封,這些都是很好的參考準則。某些時候你必須在你的密鑰被發(fā)現(xiàn)的可能性與有些只要黑客想要就一定會失去的東西之前做個平衡之后指郁,決定你要在你的應(yīng)用代碼里混淆 API 驗證序列中投入多少時間精力忙上。
本文由 SwiftGG 翻譯組翻譯,已經(jīng)獲得作者翻譯授權(quán)坡氯,最新文章請訪問 http://swift.gg晨横。