[Swift通天遁地]7、數據與安全-(20)快速實現MD5/Poly1305/Aes/BlowFish/Chacha/Rabbit

★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
➤微信公衆號:山青詠芝(shanqingyongzhi)
➤博客園地址:山青詠芝(https://www.cnblogs.com/strengthen/
➤GitHub地址:https://github.com/strengthen/LeetCode
➤原文地址:http://www.javashuo.com/article/p-mmmrhqkk-mc.html 
➤若是連接不是山青詠芝的博客園地址,則多是爬取做者的文章。
➤原文已修改更新!強烈建議點擊原文地址閱讀!支持做者!支持原創!
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★html

目錄:[Swift]通天遁地Swiftios

本文將演示如何使用第三方類庫,快速實現多種的加密算法。git

首先確保已經安裝了所需的第三方類庫,點擊查看配置文件。github

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】打開項目。swift

在左側的項目導航區,打開試圖控制器的代碼文件【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高級加密標準算法。
    //這是美帝政府採用的一種區塊加密標準,
    //可使用12八、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.
    }
}
相關文章
相關標籤/搜索