淺談iOS中經常使用加密算法的使用

 之前若是咱們忘記了登陸密碼,一般能夠經過「找回密碼」這樣的方式拿回密碼,那說明你的隱私數據在他們的數據庫中是明文保存的,如今請切記:若是哪一個平臺還有這樣的方式請馬上立刻註銷你的帳號,並避免在任何其餘平臺使用這個平臺使用過的密碼。請堅信:在網絡世界中,只要是明文存在或可逆的東西,都是不安全的。沒有哪家公司會告訴你他們的數據庫被拖庫過,你更沒法想象如今的黑色產業早已讓你毫無隱私。ios

 千萬別一個密碼走天下,必定要按期改密碼!git

 道高一尺魔高一丈,對用戶隱私及一些敏感數據的保護愈來愈重要,在iOS中,蘋果封裝了Security.framework、CommonCrypto.framework這兩個保護信息安全的庫,爲咱們提供了安全相關的通用API:

  • RSA:公私鑰的生成、公鑰加密、私鑰解密、私鑰簽名、公鑰驗籤功能,證書信息的讀取,以及密鑰在KeyChain中存儲,查找,刪除等功能
  • 哈希:SHA一、SHA22四、SHA25六、SHA38四、SHA512 MD二、MD四、MD5
  • 對稱加密:DES、3DES、AES

 這一篇文章,咱們就以「用戶輸入密碼,登陸,服務端驗證用戶信息,用戶上傳隱私數據」這個常見場景爲例,分享一些密碼學常識和加密時經常使用的防破解技巧,至於上述算法相關API的使用,文末我會附上iOS中全部經常使用加密API使用的demo,這裏就不浪費篇幅貼代碼了。先說兩個保護用戶隱私的原則:github

  • 網絡上不容許明文傳遞用戶隱私信息
  • 本地不容許明文保存用戶隱私信息

 再瞭解下幾種算法的特色:算法

對稱加密

  • 加密解密共用一個密鑰
  • DES 數據加密標準,安全強度不夠已經不多用了
  • 3DES 使用三個密鑰對相同的數據執行三次加密 強度略高,但密鑰的保護一直是個隱患因此也不經常使用
  • AES 高級密碼標準 用得最多
  • 兩種經常使用加密模式:
    • ECB:
       最基本的加密方式,無初始向量,相同的明文永遠生成不變的密文,容易受到密碼本重放攻擊,不多用
    • CBC:
       明文被加密前要與前面的密文進行異或運算後再加密,所以只要選擇不一樣的初始向量,相同的密文加密後會造成不一樣的密文,這是目前應用最普遍的模式。CBC加密後的密文是上下文相關的,但明文的錯誤不會傳遞到後續分組,但若是一個分組丟失,後面的分組將所有做廢(同步錯誤)。
       能夠有效的保證密文的完整性,若是一個數據塊在傳遞是丟失或改變,後面的數據將沒法正常解密。

RSA

關於RSA相關知識請參考:
非對稱加密--RSA原理淺析
RSA的主場-證書籤名之OpenSSL演示數據庫

這裏再也不贅述。macos

哈希算法

也就是常說的散列函數,嚴格意義上它並非一種加密算法,但它經常與加密算法一塊兒出現,做爲一種組合方式。哈希具備如下特色:編程

  • 算法是公開的
  • 對相同的數據運算,獲得的結果是同樣的
  • 同一算法對不一樣的數據運算,獲得的結果長度是固定的,如MD5的結果必定是128bit,32個字符(16進製表示),因此散列碰撞是必然的偶然
  • 不可逆,可是能夠經過彩虹表反查詢
  • 一般做爲信息「指紋」--信息摘要,用來作數據識別(版權、搜索引擎、數字簽名等)。

實際應用

 知道了每種算法的特色,回到應用場景:用戶輸完密碼點擊登陸時,咱們如何保證用戶信息是足夠安全的呢?安全

  • 對稱加密:密鑰傳輸有隱患,且在客戶端加密前和服務端解密後會出現明文,不安全。
  • RSA:安全性高,網絡劫持很難破解,可是服務端拿到客戶端加密後的密文怎麼辦呢?用私鑰解密,解密以後拿到明文信息?大忌,沒有哪一個服務端是安全的,更無法保證數據庫人員的我的泄露用戶信息。不可取。
  • 哈希:
    • 直接MD5?用戶輸入常規組合機率很大,暴力破解風險很高,不可取。本地加鹽,很變態的鹽?安全性有必定保障,缺點是鹽寫死在程序裏了,寫代碼的人也有泄露的可能性,一旦泄漏結果是毀滅性的,不可取。
    • HMAC:Keyed-Hashing for Message Authentication,這是一種使用單向散列函數來構造消息認證碼的方案,而不是算法。
        在第一次註冊時,服務端下發一個隨機密鑰 n,這個密鑰會在客戶端和服務端都保存一份(支持服務端更新),客戶端的 n 用做之後每次登陸時的「鹽」參與第一次散列運算,並將第一次散列運算的結果 s 發給服務端做爲用戶密碼信息保存到數據庫中,這樣用戶的真實密碼不管是客戶端仍是服務端都不知道,也不存在數據庫被拖庫泄露的問題。服務端保存的 n 用於當用戶換設備登陸或卸載從新裝時驗證經過後再次將 n 下發給客戶端保存。
       用戶每次登陸時,服務器會再動態下發一個隨機值做爲密鑰,並在會話中記下這個隨機值 r,客戶端先用本地保存的 n 對用戶密碼作散列運算獲得 s ,再用 r 對 s 作一次MAC(Message Authentication Codes)運算並將運算結果發送給服務端,服務端也從數據庫中取出用戶的密碼散列值作一樣的運算,並將結果與客戶端進行對比。爲了防止網絡中間人攻擊,還需將時間戳(服務器時間,通常精確到分鐘)參與校驗,黑客就很難破解了。這是目前最主流的安全方案。

 如今用戶登陸成功,如今要上傳一份敏感數據,咱們如何保證數據的完整性呢?結合上面的分析,推薦AES的CBC加密方式,安全性高,還能保證完整性,數字簽名一樣也能夠驗證數據完整性,用RSA對數據的hash值進行加密,服務端接收完數據後,用私鑰解密獲得hash值,與接收數據的hash值做比對。bash

補充:

iOS中常見加密算法的使用:EncryptDemo
在Demo中,對稱加密AES的加密解密函數:服務器

CCCryptorStatus CCCrypt(
    CCOperation op,         /* kCCEncrypt, etc. */
    CCAlgorithm alg,        /* kCCAlgorithmAES128, etc. */
    CCOptions options,      /* kCCOptionPKCS7Padding, etc. */
    const void *key,
    size_t keyLength,
    const void *iv,         /* optional initialization vector */
    const void *dataIn,     /* optional per op and alg */
    size_t dataInLength,
    void *dataOut,          /* data RETURNED here */
    size_t dataOutAvailable,
    size_t *dataOutMoved)
    API_AVAILABLE(macos(10.4), ios(2.0));  
複製代碼

調用CCCrypt時,用戶敏感數據不要直接做爲參數傳遞,不然逆向很容易hook到,一般的作法是對敏感數據作異或、加鹽等處理,具體根據須要本身設計。

iOS app簽名機制詳解 推薦閱讀:
iOS應用簽名(上)
iOS應用簽名(下)

iOS中對鑰匙串的操做推薦:SSKeyChain

實踐出真知,咱們下篇再會~

老規矩,有錯誤請積極指正,有問題請踊躍留言。

更多一手好文更新,請關注個人我的微信公衆號:面向將來編程 撒花✧(≖ ◡ ≖✿)

相關文章
相關標籤/搜索