1.通過私鑰生成.csr文件
openssl req -new -key private.pem -out rsacert.csr
要用.csr到專門頒發證書的機構去簽名,簽名證書是合法的,也能自己進行簽名,但是自簽的簽名是沒有被認證的
openssl x509 -req -days 3650 -in rsacert.csr -signkey private.pem -out rsacert.crt
收到一個crt的證書,此證書的作用是比如做https服務器,需要將這個證書放到公司的服務器上,讓請求方去接收
.crt證書轉成能使用的der證書,從蘋果拿到的是der證書,會在本地鑰匙串中對它綁定一個密鑰,即p12,der證書里面的p12
openssl x509 -outform der -in rsacert.crt -out rsacert.der
獲取p12文件,p12和der是一對,兩個文件可以在代碼里面做加解密,iOS中通過der和p12這兩個文件進行加解密,代碼里面只能用der證書,加密完后的文件格式是二進制data
base64編碼message.txt為abc.txt,Base64編碼由0-9,a-z,A-Z,+/=65個字母組成,如果要編碼的字節數不能被3整除,最后會多出1或2個字節,則先使用0字節值在末尾補足,使其能夠被3整除,然后再進行Base64的編碼。在編碼后的Base64文本后加上一個或兩個=號,代表補足的字節數。也就是說,當最后剩余兩個八位(待補足)字節(2個byte)時,最后一個6位的Base64字節塊有四位是0值,最后附加上兩個等號;如果最后剩余一個八位(待補足)字節(1個byte)時,最后一個6位的base字節塊有兩位是0值,最后附加一個等號。
編碼:base64 message.txt -o abc.txt
解碼:base64 abc.txt -o 123.txt -D
Base64只適用于表示二進制文件,Base64編碼后文件會大1/3,不適用于大型的數據編碼
RSA對代碼進行加密,加密后是二進制文件,用Base64打印排查錯誤,查看能不能加密成功
2.RSA加密
兩次的加密結果不一樣,是因為RSA內部的填充模式
kSecPaddingNone 不填充,密文每次都不會變化
通過RSA和服務端通訊,公鑰放客戶端,私鑰放服務端
對稱加密(KEY)定期來一次變化,服務端通過私鑰給KEY加密,傳送到客戶端,客戶端通過公鑰解密,之后通過KEY對稱加密進行通訊
客戶端中存在公鑰,一旦發現公鑰泄露,可以換公鑰,所有APP統一換,私鑰在網絡上不傳遞,只在公司服務器上有
RSA最常見的使用場景是做簽名
3.HASH
HASH:MD5,SHA1,SHA256,SHA512
對稱加密:DES,3DES,AES
Hash,一般翻譯做“散列”,也有直接音譯為“哈?!钡?,就是把任意長度的輸入通過散列算法變換成固定長度的輸出,該輸出就是散列值。這種轉換是一種壓縮映射,也就是,散列值的空間通常遠小于輸入的空間,不同的輸入可能會散列成相同的輸出,所以不可能從散列值來確定唯一的輸入值。簡單的說就是一種將任意長度的消息壓縮到某一固定長度的消息摘要的函數
- 算法是公開的
- 對相同數據運算,得到的結果是一樣的
- 對不同數據運算,如MD5得到的結果默認是128位,32個字符(16進制標識)。
- 這玩意沒法逆運算
- 信息摘要,信息“指紋”,是用來做數據識別的。
I.數據(無限大或長) HASH運算 結果為16^32(有限長) 必然會有兩個或多個不同的數據,擁有同樣的HASH值,這就是散列碰撞
II.HASH用途
- 用戶密碼的加密
- 搜索引擎
- 版權
- 數字簽名
III.用戶密碼加密
服務端不能保存用戶的明文密碼,開發者都不知道用戶的真實密碼最安全
網絡傳輸數據(隱私數據),不能明文,本地保存數據(隱私數據),不能明文。
對密碼進行處理
A.密碼直接進行md5,但有專門反md5的網站https://www.cmd5.com/,不安全
B.給密碼加鹽,但鹽已經泄露給開發者,也有泄露風險
C.HMAC:KEY由服務器提供,一個賬號一個KEY
用戶注冊是去服務端查詢,此賬號是否有KEY綁定,若沒有即首次,分配一個key,此時可通過RSA加密的方式分配KEY,若是同一個賬號換一臺新手機,先去服務端請求KEY,表現形式是向用戶的設備上請求用戶授權,最典型的例子是蘋果AppID登錄新設備時,會讓在已經登錄過的設備上進行授權,既能方便獲取HMAC加密的key,也能讓用戶感知到登錄的安全,可以通過保存手機設備的MAC的地址來判斷是否要返回KEY到客戶端
本地保存KEY,最好用鑰匙串keychain訪問,不要自己放沙盒,鑰匙串訪問本身進行加密了,可以保存明文或密文,鑰匙串訪問存進去是加密的,取出來是解密的
鹽在App中不好更新,而HMAC中的KEY,可以隨時通過服務端更新,比如,用戶輸入正確密碼后,即用的老的KEY登錄了,服務端返回新的KEY可以將老的KEY替換掉,所有的設備都能替換掉,KEY只針對綁定KEY的用戶
此時,用戶的密碼是安全了,但是仍舊可以攔截KEY加密后的HASH值,進行模擬登錄,怎樣避免呢?
D:HMAC+時間戳
客戶端用密碼的HMAC哈希值+當前時間到分鐘進行md5加密后請求服務端,服務端接收到請求后,用服務端的當前時間比客戶端的時間晚一分鐘+HMAC哈希值進行md5加密后進行匹配,若無法匹配,服務端將時間往前推一分鐘再次進行匹配,黑客若想攔截登錄此密碼必須在1分59秒之內完成,否則無法進行模擬登錄
一分兩分鐘的時間戳由自己決定,每次加密的結果不一樣,受時間的影響特別大,使用的時間戳為服務器返回的時間戳,每次請求都返回時間戳,不會使用手機本地時間
4.HASH其他用途
I.搜索
搜索關鍵字:iOS 深圳 cloud
會將這三個字符串的HASH值相加,三個128個二進制位相加,本身是一串數字,展現出來是16進制表現形式為字符串
iOS:1bdf605991920db11cbdf8508204c4eb
深圳:7a399889b9a4aed64afd0cf95941b975
cloud:a1234b3161b4fbfdfb96dd576b65bbea
會將三個相加得到的結果是一個數字,在詞庫中搜索這個數字,則搜到的結果和排列組合無關,因為相加的結果始終相同
II.版權
文件上傳到網站,會保存HASH數據。圖片、視頻,看到的和原始文件是不一樣的,肉眼看不出來,對比知道哪個是正版哪個是盜版
網盤做數據識別用哈希值
helloworld.txt更改文件名葫蘆兄弟.mp3后,哈希值并沒有改變,敏感文件會被刪掉,改名字沒有用,哈希值沒有變化
若希望哈希值發生變化,可以通過Base64轉化,但此時文件會變大
若希望哈希值發生變化,文件變小,可以轉化為zip文件
二進制文件的本質發生變化,哈希值才會發生變化
網盤中去識別數據,根據哈希值來識別
代碼函數中提供終端命令,方便試算
#pragma mark - 散列函數
/**
* 計算MD5散列結果
*
* 終端測試命令:
* @code
* md5 -s "string"
* @endcode
*
* <p>提示:隨著 MD5 碰撞生成器的出現,MD5 算法不應被用于任何軟件完整性檢查或代碼簽名的用途。<p>
*
* @return 32個字符的MD5散列字符串
*/
- (NSString *)md5String;
/**
* 計算SHA1散列結果
*
* 終端測試命令:
* @code
* echo -n "string" | openssl sha -sha1
* @endcode
*
* @return 40個字符的SHA1散列字符串
*/
- (NSString *)sha1String;
/**
* 計算SHA256散列結果
*
* 終端測試命令:
* @code
* echo -n "string" | openssl sha -sha256
* @endcode
*
* @return 64個字符的SHA256散列字符串
*/
- (NSString *)sha256String;
/**
* 計算SHA 512散列結果
*
* 終端測試命令:
* @code
* echo -n "string" | openssl sha -sha512
* @endcode
*
* @return 128個字符的SHA 512散列字符串
*/
- (NSString *)sha512String;
#pragma mark - HMAC 散列函數
/**
* 計算HMAC MD5散列結果
*
* 終端測試命令:
* @code
* echo -n "string" | openssl dgst -md5 -hmac "key"
* @endcode
*
* @return 32個字符的HMAC MD5散列字符串
*/
- (NSString *)hmacMD5StringWithKey:(NSString *)key;
/**
* 計算HMAC SHA1散列結果
*
* 終端測試命令:
* @code
* echo -n "string" | openssl sha -sha1 -hmac "key"
* @endcode
*
* @return 40個字符的HMAC SHA1散列字符串
*/
- (NSString *)hmacSHA1StringWithKey:(NSString *)key;
/**
* 計算HMAC SHA256散列結果
*
* 終端測試命令:
* @code
* echo -n "string" | openssl sha -sha256 -hmac "key"
* @endcode
*
* @return 64個字符的HMAC SHA256散列字符串
*/
- (NSString *)hmacSHA256StringWithKey:(NSString *)key;
/**
* 計算HMAC SHA512散列結果
*
* 終端測試命令:
* @code
* echo -n "string" | openssl sha -sha512 -hmac "key"
* @endcode
*
* @return 128個字符的HMAC SHA512散列字符串
*/
- (NSString *)hmacSHA512StringWithKey:(NSString *)key;
#pragma mark - 文件散列函數
/**
* 計算文件的MD5散列結果
*
* 終端測試命令:
* @code
* md5 file.dat
* @endcode
*
* @return 32個字符的MD5散列字符串
*/
- (NSString *)fileMD5Hash;
/**
* 計算文件的SHA1散列結果
*
* 終端測試命令:
* @code
* openssl sha -sha1 file.dat
* @endcode
*
* @return 40個字符的SHA1散列字符串
*/
- (NSString *)fileSHA1Hash;
/**
* 計算文件的SHA256散列結果
*
* 終端測試命令:
* @code
* openssl sha -sha256 file.dat
* @endcode
*
* @return 64個字符的SHA256散列字符串
*/
- (NSString *)fileSHA256Hash;
/**
* 計算文件的SHA512散列結果
*
* 終端測試命令:
* @code
* openssl sha -sha512 file.dat
* @endcode
*
* @return 128個字符的SHA512散列字符串
*/
- (NSString *)fileSHA512Hash;
5.數字簽名
數字簽名目的:驗證這段二進制數據是否是原始機構頒發的
服務端傳輸數據的時候,傳送二進制數據和二進制數據的哈希值
客戶端收到數據的時候,計算二進制數據的哈希值和服務端返回的二進制哈希值是否匹配,若不匹配,則說明數據被篡改過,丟棄不用,此時,若二進制數據被篡改,二進制數據的哈希值也被篡改,則無法識別,需要將二進制數據的哈希值,128位屬于小數據,用RSA進行加密傳送到客戶端,客戶端解密后和計算的二進制數據哈希值進行對比,防止數據被篡改
RSA加密二進制數據哈希值的這一段數據成為數字簽名
數字簽名應用非常廣泛,支付寶,銀行,支付平臺都是用數字簽名,iOS也使用代碼簽名
要想篡改,只能拿到服務端的私鑰,而私鑰基本上拿不到的