MD5
什麼是MD5
它是一種信息摘要算法,並不是加密算法(以下是習慣性的說成MD5加密),它可以從一個字符串或一個文件中按照一定的規則生成一個特殊的字符串(這個特殊的字符串就被稱之爲摘要,我理解就是從文件中摘一些信息片段加工而來),並且一個文件所對應的MD5摘要是固定的,當文件內容變化後,其MD5值也會不一樣。MD5值就是指這串32位的由“0-9,a-f”所組成的字符串
MD5的特點:
- 不可逆運算
- 對不同的數據加密的結果是定長的32位字符(不管文件多大都一樣)
- 對相同的數據加密,得到的結果是一樣的(也就是複製)。
- 抗修改性 : 信息“指紋”,對原數據進行任何改動,哪怕只修改一個字節,所得到的 MD5 值都有很大區別.
- 確定性 : 已知原數據和其 MD5 值,想找到一個具有相同 MD5 值的數據(即僞造數據)是非常困難的.
- 碰撞性: 想找到兩個不同數據,使他們具有相同的 MD5 值,是非常困難的
MD5 應用:
-
對密碼進行加密,移動端會將用戶密碼通過MD5加密轉換後發送給服務器,服務器會在數據庫中保存加密後的md5值。這樣做的好處是不會直接發送明文密碼、服務器管理人員也無法確切的知道密碼。但是一旦拿到密碼的md5值後仍然存在被暴力破解的可能性。破解網站
-
文件的完整性校驗,在傳遞文件的過程中附帶傳遞文件的md5值,接收端通過比較文件的md5值判斷文件的完整性。
增強MD5的安全性
1.對明文多次MD5加密,對明文加密之後的MD5串再次進行MD5加密
2.MD5加鹽(salt),基本過程是這樣的:當需要對明文進行MD5加密的時候,程序會添加一個salt值跟明文一起進行MD5加密,這樣可以極大增強MD5被破解的難度。salt值可以是隨機字符串或者username+password這種形式,當使用隨機字符串作爲salt加密是通常需要將salt一起上傳服務器進行保存。
代碼實現
import Foundation
import CommonCrypto
extension String{
var md5:String {
let str = self.cString(using: String.Encoding.utf8)
let strLen = CUnsignedInt(self.lengthOfBytes(using: String.Encoding.utf8))
let digestLen = Int(CC_MD5_DIGEST_LENGTH)
let result = UnsafeMutablePointer<UInt8>.allocate(capacity: 16)
CC_MD5(str, strLen, result)
let hash = NSMutableString()
for i in 0 ..< digestLen {
hash.appendFormat("%02x", result[i])
}
free(result)
return String(format: hash as String)
}
}
print("這是MD5".md5)
SHA 安全散列算法
什麼是SHA
安全散列算法(英語:Secure Hash Algorithm,縮寫爲SHA)是一個密碼散列函數家族.
和MD5類似,安全散列算法可以根據字符串生成一定長度的摘要信息,該摘要信息不可逆轉,且不同的字符串的摘要信息相同的概率極低。
SHA家族的五個算法,分別是SHA-1、SHA-224、SHA-256、SHA-384,和SHA-512,由美國國家安全局(NSA)所設計,並由美國國家標準與技術研究院(NIST)發佈;是美國的政府標準。後四者有時並稱爲SHA-2。SHA-1在許多安全協定中廣爲使用,包括TLS和SSL、PGP、SSH、S/MIME和IPsec,曾被視爲是MD5(更早之前被廣爲使用的雜湊函數)的後繼者。
SHA的使用
import Foundation
import CommonCrypto
extension String{
enum SHAType{
case sha1,sha224,sha256,sha384,sha512
}
func sha(_ type:SHAType) -> String{
var digestLen:Int = 0
switch type {
case .sha1:
digestLen = Int(CC_SHA1_DIGEST_LENGTH)
case .sha224:
digestLen = Int(CC_SHA224_DIGEST_LENGTH)
case .sha256:
digestLen = Int(CC_SHA256_DIGEST_LENGTH)
case .sha384:
digestLen = Int(CC_SHA384_DIGEST_LENGTH)
case .sha512:
digestLen = Int(CC_SHA512_DIGEST_LENGTH)
}
let unsafePointer = self.cString(using: String.Encoding.utf8)
let strLen = CUnsignedInt(self.lengthOfBytes(using: String.Encoding.utf8))
let result = UnsafeMutablePointer<UInt8>.allocate(capacity: digestLen * 2)
switch type {
case .sha1:
CC_SHA1(unsafePointer, strLen, result)
case .sha224:
CC_SHA224(unsafePointer, strLen, result)
case .sha256:
CC_SHA256(unsafePointer, strLen, result)
case .sha384:
CC_SHA384(unsafePointer, strLen, result)
case .sha512:
CC_SHA512(unsafePointer, strLen, result)
}
let hash = NSMutableString()
for i in 0 ..< digestLen {
hash.appendFormat("%02x", result[i])
}
free(result)
return String(format: hash as String)
}
}
print("這是SHA".sha(.sha1))
print("這是SHA".sha(.sha224))
print("這是SHA".sha(.sha256))
print("這是SHA".sha(.sha384))
print("這是SHA".sha(.sha512))
/*輸出:
859aa498c20aa785a1e516052d553bfaddc6271c
3d4374ec9ee000f77821730f0ee71394b71b18e65c747032018f841c
4ba0bcea71b037b45b759735a47cf173fb3e40ee4eabdf3ddeb3fe0c096d71f9
df1b5170eeb6c665a09a20ca763768a5026bfd294ebb2c80384d43e347ea5ffaf1746fa292ab2d97bd6ff87076e3496c
a40560b861adf2daeb8d5c81e8eb099067e33b60d4f1cfa8555c7ab991ea022a45f29e70aaa26b6ee59adab8cd52677b653524aea12758f2d798463981818d65
*/
Base64編碼
什麼是Base64
**Base64不是加密方式,而是編碼方式,是網絡上最常見的用於傳輸8Bit字節碼的編碼方式之一。**Base64就是一種基於64個可打印字符來表示二進制數據的方法。Base64編碼是從二進制到字符的過程,可用於在HTTP環境下傳遞較長的標識信息。採用Base64編碼具有不可讀性,需要解碼後才能閱讀。
####Base64的原理
可以參考Base64的原理
Base64的使用
extension String{
///base64 解碼
var base64Decoded: String? {
guard let decodedData = Data(base64Encoded: self) else { return nil }
return String(data: decodedData, encoding: .utf8)
}
///base64 編碼
var base64Encoded: String? {
let plainData = data(using: .utf8)
return plainData?.base64EncodedString()
}
}
let a = "這是base64編碼".base64Encoded
print(a ?? "") //6L+Z5pivYmFzZTY057yW56CB
print(a?.base64Decoded ?? "") //這是base64編碼