[Swift通天遁地]七、數據與安全-(20)快速實現MD5/Poly1305/Aes/BlowFish/Chacha/Rabbit
阿新 • • 發佈:2019-02-04
targe () 隨著 after cbc crypto 格式 ride super
本文將演示如何使用第三方類庫,快速實現多種的加密算法。
首先確保已經安裝了所需的第三方類庫,點擊查看配置文件。
1 platform :ios, ‘8.0‘ 2 use_frameworks! 3 4 target ‘DemoApp‘ do 5 source ‘https://github.com/CocoaPods/Specs.git‘ 6 pod ‘CryptoSwift‘, :git => "https://github.com/krzyzanowskim/CryptoSwift", :branch => "master" 7 end
根據配置文件的相關設置,安裝第三方類庫。
安裝完成之後,點擊【DemoApp.xcworkspace】打開項目。
在左側的項目導航區,打開試圖控制器的代碼文件【ViewController.swift】
現在開始編寫代碼,依次使用多個加密算法,對字符串進行加密。
import UIKit //在當前的類文件中,引入已經安裝的第三方類庫 import CryptoSwift class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib.//MD5加密 testMD5() //SHA(安全散列)加密算法 testSHA() //Poly1305算法常用於驗證數據的完整性和真實性 testPoly1305() //AES高級加密標準算法 aesTest() //演示河豚加密和解密算法 blowfishTests() //河豚加密和解密算法 blowfishTests() //來自Google的加密算法,是性能不強的設備上,使用最佳的算法。 chaCha20Tests()//如何在字符串類型和8位無符號整形數組之間進行相互轉換 stringAndUInt8Array() //兔子加密算法,流加密算法。 rabbitTests() } //添加一個方法 ,用來演示MD5加密算法 func testMD5() { //通過調用字符串對象的擴展方法,對字符串進行加密。 //並在控制臺輸出密文 print("MD5:"+"Strengthen".md5()) //對字符串進行加密, //無論字符串的長度是多少,加密後的密文長度都是固定的。 print("MD5:"+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789".md5()) //初始化一個8位無符號整數類型的數組對象。 let data = [0x31, 0x32, 0x33] as Array<UInt8> //通過調用摘要的類方法,對數組進行加密, //並在控制臺輸出密文。 print("MD5:\(Digest.md5(data))") } //添加一個方法 ,用來演示SHA(安全散列)加密算法 //隨著加密算法版本的增加,密文的長度也在增長,解密的難度也在增加。 func testSHA() { //通過調用第一版算法對象的計算方法,將制定的內容進行加密, //並存儲在一個常量中。第一版的算法已經被Google破解。 let sha1 = SHA1().calculate(for: Array<UInt8>(hex: "CoolKeTang")).toHexString() //在控制臺輸出密文。 print("SHA1:\(sha1)") //通過調用第二版算法對象的計算方法,將制定的內容進行加密, //並存儲在一個常量中。 let sha2 = SHA2(variant: .sha224).calculate(for: Array<UInt8>(hex: "CoolKeTang")).toHexString() //在控制臺輸出密文。 print("SHA2:\(sha2)") //通過調用第三版算法對象的計算方法,將制定的內容進行加密, //並存儲在一個常量中。 let sha3 = SHA3(variant: .sha512).calculate(for: Array<UInt8>(hex: "CoolKeTang")).toHexString() //在控制臺輸出密文。 print("SHA2:\(sha3)") } //添加一個方法 ,Poly1305算法常用於驗證數據的完整性和真實性 func testPoly1305() { //初始化一個8位無符號整形的數組對象,作為加密的密鑰。 let key: Array<UInt8> = [0xdd, 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc] //初始化一個8位無符號整形的數組對象。作為待加密的內容。 let msg: Array<UInt8> = [0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0, 0xc1] //初始化第三個數組對象,作為正確的驗證代碼。 let expectedMac: Array<UInt8> = [0xdd, 0xb9, 0xda, 0x7d, 0xdd, 0x5e, 0x52, 0x79, 0x27, 0x30, 0xed, 0x5c, 0xda, 0x5f, 0x90, 0xa4] //計算消息的身份驗證代碼 let mac = try! Poly1305(key: key).authenticate(msg) //在控制臺輸出y消息身份驗證代碼 print("mac:\(mac)") //測試消息身份代碼,是否和正確的驗證代碼相同, //如果不相同,則輸出信息被破壞,或被植入惡意內容提示。 if mac != expectedMac { print("Invalid authentication result") } //將8位無符號整形的數組對象,轉換成數據類型。 let msgData = Data(bytes: msg) //通過消息對象的擴展方法, //同樣可以計算消息的身份驗證代碼。 let mac2 = try! msgData.authenticate(with: Poly1305(key: key)) //在控制臺輸出消息驗證代碼。 print("mac2:\(mac2)") //使用相同的方式,測試消息身份驗證代碼, //是否和正確的驗證代碼相同, if mac2 != Data(bytes: expectedMac) { //如果不相同則輸出信息,如果不相同則輸出信息有可能被破壞的提示 print("Invalid authentication result") } } //添加一個方法 ,AES高級加密標準算法。 //這是美帝政府采用的一種區塊加密標準, //可以使用128、192和256位的加密密鑰。 func aesTest() { //初始化一個8位無符號整形的數組對象,作為待加密的輸入數據。 let input = Array("123456".utf8) //初始化另一個8位無符號整形的數組對象,作為加密的密鑰。 let key = "679fb1ddf7d81bee" //let key = Array("2021cakjpVPy6KlvmHiLO49dICXo7WMnsNJw".utf8) //let input: Array<UInt8> = [0,1,2,3,4,5,6,7,8,9] //let key: Array<UInt8> = [0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00] //生成一個初始化向量,用來增加加密算法的強度。 let iv = "kdf67398DF7383fd" //通過一個異常捕捉語句,用來執行加密操作。 do { //對輸入數據進行加密,並使用一個常量存儲密文。 let encrypted = try AES(key: key, iv: iv, padding: .noPadding).encrypt(input) //對密文進行解密操作,使用一個常量存儲解密後的內容。 let decrypted = try AES(key: key, iv: iv, padding: .noPadding).decrypt(encrypted) //在控制臺輸出密文和解密後的內容。 print("encrypted:\(encrypted)") print("decrypted:\(decrypted)") } catch { print(error) } } //添加一個方法 ,演示河豚加密和解密算法。 //自從32位處理器誕生後,該算法在加密速度上,就超越了3DES加密算法。引起關註。 func blowfishTests() { //這是一種對成的加密算法,每次加密一個64位分組, //使用32位至448位對可變長度的密鑰。 //加密過程分為兩個階段:密鑰預處理、信息加密。 let key = Array<UInt8>.init(hex: "0123456789ABCDEFF0E1D2C3B4A59687") //同樣使用到初始化向量,用來增加加密算法的強度。 let iv = Array<UInt8>.init(hex: "FEDCBA9876543210") //初始化一個8位無符號整形的數組對象, //作為待加密的輸入數據。 let input = Array<UInt8>.init(hex: "37363534333231204E6F77206973207468652074696D6520666F722000") //通過一個異常捕捉語句,用來執行加密操作。 do { //初始化一個加密對象 let cipher = try Blowfish(key: key, blockMode: CBC(iv: iv), padding: .pkcs7) //使用加密對象,對輸入的數據進行加密,並使用一個常量存儲密文 let ciphertext = try cipher.encrypt(input) //將密文進行解密,同樣使用一個常量存儲解密後的內容。 let plaintext = try cipher.decrypt(ciphertext) //在控制臺輸出密文和解密後的內容。 print("ciphertext:\(ciphertext)") print("plaintext:\(plaintext)") //如果解密後的內容和輸入的內容不同 if(plaintext != input) { //則在控制臺輸出操作失敗的提示信息 print("Invalid result.") } } catch { print(error) } } //添加一個方法 ,來自Google的加密算法, //這是谷歌開發的一款更快更強大的加密算法。 //是性能不強的設備上,使用最佳的算法。 func chaCha20Tests() { //初始化一個8位無符號整形的數組對象。作為加密的密鑰。 let key : Array<UInt8> = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] //創建一個初始化向量,用來增加加密算法的強度。 let iv : Array<UInt8> = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] //初始化一個字符串常量 let expectedHex = "76B8E0ADA0F13D90405D6AE55386BD28BDD219B8A08DED1AA836EFCC8B770DC7DA41597C5157488D7724E03FB8D84A376A43B8F41518A11CC387B669B2EE6586" //創建一個長度位字符串長度一半的,8位無符號整形的數組對象,其內容都是數字0。 let message = Array<UInt8>(repeating: 0, count: (expectedHex.count / 2)) //添加一個異常捕捉語句,用來執行加密和解密的操作。 do { //通過加密對象,使用指定的密鑰,對數據進行加密。 //並使用一個常量存儲密文 let encrypted = try ChaCha20(key: key, iv: iv).encrypt(message) //使用指定的密鑰,對數據進行解密。 //並使用一個常量存儲密文。 let decrypted = try ChaCha20(key: key, iv: iv).decrypt(encrypted) //依次在控制臺輸出密文和解密後的內容。 print("encrypted:\(encrypted)") print("decrypted:\(decrypted)") //如果解密後的內容和輸入的內容不同 if (message != decrypted) { //則在控制臺輸出操作失敗的提示信息 print("ChaCha20 decryption failed") } } catch { print(error) } } //添加一個方法 //上方進行加密解密的內容,都是8位無符號整形的數組對象, //通過這個方法,如何在字符串類型和8位無符號整形數組之間進行相互轉換。 func stringAndUInt8Array() { //通過調用數組對象的初始化方法, //即可將字符串對象,轉換成8位無符號整形數組。 let uInt8Array = Array("https://www.cnblogs.com/strengthen/".utf8) //在控制臺輸出轉換後的結果 print("uInt8Array:\(uInt8Array)") //通過字符串類型的初始化方法, //將一個8位無符號整形數組,轉換成指定編碼格式的字符串對象。 let string = String(bytes: uInt8Array, encoding: .utf8) //在控制臺c輸出轉換後的結果 print("string:\(String(describing: string))") } //添加一個方法 ,兔子加密算法。 //該算法的密鑰長度位128,最大加密消息的長度位16字節。 //這是目前加密解密速度都比較高效的流加密算法。 func rabbitTests() { //初始化一個8位無符號整形的數組對象,作為加密的密鑰。 let key : Array<UInt8> = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] //創建用於加密的內容 let url = "https://www.cnblogs.com/strengthen/" //並將內容轉換成8位無符號的整形數組。 let message = Array(url.utf8) //初始化一個兔子加密對象 let rabbit = try! Rabbit(key: key) //通過加密對象,使用指定的密鑰,進行數據的加密, //並使用一個常量存儲密文。 let cipherText = try! rabbit.encrypt(message) //使用指定的密鑰,對密文進行解密, //並使用一個常量存儲解密後的內容。 let decrypted = try! rabbit.decrypt(cipherText) //將解密後的內容,恢復為字符串的類型。 let plainText = String(bytes: decrypted, encoding: .utf8) //在控制臺輸出密文和解密後的內容。 print("cipherText:\(cipherText)") print("plainText:\(String(describing: plainText))") //如果解密後的內容和輸入的內容不同 if url != plainText { //則在控制臺輸出操作失敗的提示信息 print("Rabbit decryption failed") } } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } }
[Swift通天遁地]七、數據與安全-(20)快速實現MD5/Poly1305/Aes/BlowFish/Chacha/Rabbit