在本文中,我們將研究ios應用程式中使用者資料加密的高階用法。 我們將從高角度研究aes加密開始,然後繼續研究如何在swift中實現aes加密的一些示例。
如果要儲存大量的自定義資料,而這些資料僅在使用者或裝置通過身份驗證後才可用,那麼最好使用加密框架對資料進行加密。 例如,您可能擁有乙個應用程式,可以存檔使用者儲存的私人聊天訊息或使用者拍攝的私人**,或者可以儲存使用者的財務詳細資訊。 在這些情況下,您可能希望使用加密。
應用程式中有兩種常見的流程,用於對來自ios應用程式的資料進行加密和解密。 向使用者顯示密碼螢幕,或者使用返回金鑰解密資料的伺服器對應用程式進行身份驗證。
在加密方面重新發明輪子從來都不是個好主意。 因此,我們將使用ios common crypto庫提供的aes標準。
aes是一種對給定金鑰的資料進行加密的標準。 用於加密資料的同一金鑰用於解密資料。 金鑰大小不同,並且aes256(256位)是用於敏感資料的首選長度。
rncryptor是ios上流行的加密包裝程式,支援aes。 rncryptor是乙個不錯的選擇,因為它可以使您快速啟動並執行,而不必擔心基礎細節。 它也是開源的,因此安全研究人員可以分析和審核**。
另一方面,如果您的應用程式處理非常敏感的資訊,並且您認為您的應用程式將成為目標並被破解,則可能需要編寫自己的解決方案。 這樣做的原因是,當許多應用程式使用相同的**時,這可以使黑客的工作更加輕鬆,從而使他們可以編寫破解應用程式,以在**中找到通用模式並對其應用補丁。
但是請記住,編寫自己的解決方案只會減慢攻擊者的速度,並防止自動攻擊。 您從自己的實現中獲得的保護是,黑客將需要花費時間和精力單獨破解應用程式。
無論您選擇第三方解決方案還是選擇自己推出,都必須了解加密系統的工作原理,這一點很重要。 這樣,您可以確定您要使用的特定框架是否真的安全。 因此,本教程的其餘部分將集中於編寫您自己的自定**決方案。 有了從本教程中學到的知識,您就可以判斷您是否正在安全地使用特定的框架。
我們將首先建立乙個用於加密資料的金鑰。
aes加密中乙個非常常見的錯誤是直接使用使用者密碼作為加密金鑰。 如果使用者決定使用普通密碼或弱密碼,該怎麼辦? 我們如何迫使使用者使用足夠隨機且強度足夠大(具有足夠的熵)的金鑰進行加密,然後讓他們記住它?
解決方案是金鑰拉伸 。 金鑰擴充套件通過使用鹽對雜湊值進行多次雜湊處理來從密碼派生金鑰。 鹽只是隨機資料的序列,省略該鹽是乙個常見的錯誤-鹽賦予金鑰至關重要的熵,如果沒有鹽,則如果有人使用相同的密碼,則將匯出相同的金鑰其他。
不用鹽,單詞詞典可以用來推導通用金鑰,然後可以用來攻擊使用者資料。 這稱為「字典攻擊」。 為此,使用具有對應於未加鹽密碼的公用金鑰的表。 它們被稱為「彩虹桌」。
建立鹽時的另乙個陷阱是使用不是為安全性而設計的隨機數生成功能。 乙個示例是c語言中的rand()
函式,可以從swift進行訪問。 該輸出最終可能非常可**!
為了建立安全鹽,我們將使用函式secrandomcopybytes
建立密碼安全的隨機位元組,即難以**的數字。
要使用該**,您需要在橋接頭中新增以下內容:
#import
這是建立鹽的**的開始。 我們將繼續新增以下**:
var salt = data(count: 8)
salt.withunsafemutablebytes }}
else
}
您現在可能想知道不想讓使用者在您的應用程式中提供密碼的情況。 也許他們已經在通過單一登入方案進行身份驗證。 在這種情況下,請讓您的伺服器使用安全生成器生成aes 256位(32位元組)金鑰。 對於不同的使用者或裝置,金鑰應該不同。 在對伺服器進行身份驗證時,您可以通過安全連線向伺服器傳遞裝置或使用者id,然後它可以將相應的金鑰傳送回去。
該方案有很大的不同。 如果金鑰來自伺服器,則控**務器的實體有能力讀取曾經加密過的資料(如果曾經獲得過裝置或資料)。 以後可能還會洩漏或暴露鑰匙。
另一方面,如果金鑰是從只有使用者知道的東西(使用者的密碼)派生的,那麼只有使用者才能解密該資料。 如果您要保護諸如私人財務資料之類的資訊,則只有使用者才能解鎖該資料。 如果無論如何該資訊對於實體是已知的,則讓伺服器通過伺服器側金鑰解鎖內容是可以接受的。
cbc的乙個常見陷阱是,每個下乙個未加密的資料塊都與前乙個加密的塊進行xor運算 ,以使加密更加牢固。 這裡的問題是,第乙個塊永遠不會像其他所有塊一樣獨特。 如果要加密的訊息與另乙個要加密的訊息開始時相同,則開始的加密輸出將是相同的,這將為攻擊者提供線索以弄清該訊息可能是什麼。
為了解決這個潛在的弱點,我們將使用所謂的初始化向量(iv)(乙個隨機位元組塊)開始儲存資料。 iv將與使用者資料的第乙個塊進行異或運算,並且由於每個塊都依賴於該點之前處理的所有塊,因此即使它與另乙個訊息具有相同的資料,也將確保對整個訊息進行唯一加密。資訊。 換句話說,使用相同金鑰加密的相同訊息將不會產生相同的結果。 因此,儘管鹽和iv被認為是公開的,但不應順序使用或重複使用。
我們將使用相同的安全secrandomcopybytes
函式建立iv。
var iv = data.init(count: kccblocksizeaes128)
iv.withunsafemutablebytes
}
為了完成我們的示例,我們將對kccencrypt
或kccdecrypt
使用cccrypt
函式。 因為我們使用的是分組密碼,所以如果訊息不能很好地適合分組大小的倍數,我們將需要告訴函式自動在末尾新增填充。
與加密一樣,最好遵循既定標準。 在這種情況下,標準pkcs7定義了如何填充資料。 我們通過提供kccoptionpkcs7padding
選項,告訴我們的加密功能使用此標準。 綜上所述,這是加密和解密字串的完整**。
class func encryptdata(_ cleartextdata : data, withpassword password : string) -> dictionary}}
else
}var iv = data.init(count: kccblocksizeaes128)
iv.withunsafemutablebytes
}if (setupsuccess)}}
}if cryptstatus == int32(kccsuccess)
}return outdictionary;
}
這是解密**:
class func decryp(fromdictionary dictionary : dictionary, withpassword password : string) -> data}}
var decryptsuccess = false
let size = (encrypted?.count)! + kccblocksizeaes128
var cleartextdata = data.init(count: size)
if (setupsuccess)}}
}if cryptstatus! == int32(kccsuccess)
}return decryptsuccess ? cleartextdata : data.init(count: 0)
}
最後,這是乙個測試,以確保在加密後可以正確解密資料:
class func encryptiontest()
在我們的示例中,我們打包了所有必要的資訊,並將其作為dictionary
返回,以便以後可以使用所有資訊成功解密資料。 您只需要在鑰匙串或伺服器上儲存iv和鹽。
這樣就完成了由三部分組成的有關保護靜態資料的系列文章。 我們已經看到了如何正確儲存密碼,敏感資訊和大量使用者資料。 這些技術是保護應用程式中儲存的使用者資訊的基準。
當使用者的裝置丟失或被盜時,這是巨大的風險,尤其是在最近利用漏洞來訪問鎖定的裝置時。 儘管許多系統漏洞都通過軟體更新進行了修補,但裝置本身的安全性僅與使用者的密碼和ios版本相同。 因此,應由每個應用程式的開發人員為儲存的敏感資料提供強大的保護。
當一種常用的安全體系結構受到威脅時,所有依賴該體系結構的應用程式也會受到威脅。 ios的任何動態鏈結庫(尤其是越獄裝置上的動態鏈結庫)都可以進行修補並與惡意庫交換。
因此,總是有很多東西要學習,ios上應用程式安全性的未來也在不斷發展。 ios安全架構現在甚至支援加密裝置和智慧卡! 最後,您現在了解了保護靜態資料的最佳做法,因此您需要遵循這些最佳做法!
翻譯自:
Windows DPAPI 資料加密保護介面詳解
dpapi是windows系統級對資料進行加解密的一種介面,無需自實現加解密 微軟已經提供了經過驗證的高質量加解密演算法,提供了使用者態的介面,對金鑰的推導,儲存,資料加解密實現透明,並提供較高的安全保證。dpapi提供了兩個使用者態介面,cryptprotectdata 加密資料,cryptunp...
資料的保護
一般資料保護條例 gdpr 歐盟通用資料保護條例 gdpr 取代資料保護指令95 46 ec,旨在協調整個歐洲的資料隱私法律,保護所有歐盟公民的資料隱私,並重塑整個地區在儲存和處理隱私資料上的管理方式。由於違反gdpr的規定,組織可能會被罰款高達全球年營業額的4 或2000萬歐元。比如,如果沒有客戶...
比較實用的加密保護檔案的方法
最近因需要記住的密碼太多。個人也沒有刻意去記住相關密碼的習慣故總是忘記,原本可以txt方式記住但是,這種記錄方式,雖然方便自己,但是會有很大的危險性,故總結了幾種比較安全的方式。1.dos保護檔案。這是個很老的保護自己的檔案不被輕易開啟的方式。1.開始 執行 cmd進入命令介面 在命令列輸入 md ...