[Swift通天遁地]七、数据与安全,20快速实现MD5/Poly1305/Aes/BlowFish/Chacha/Rabbit

★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★

➤微信公众号:山青咏芝(shanqingyongzhi)

➤博客园地址:山青咏芝(https://www.cnblogs.com/strengthen/

➤GitHub地址:https://github.com/strengthen/LeetCode

➤原文地址:

➤如果链接不是山青咏芝的博客园地址,则可能是爬取作者的文章。

➤原文已修改更新!强烈建议点击原文地址阅读!支持作者!支持原创!

★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★

热烈欢迎,请直接点击!!!

进入博主App Store主页,下载使用各个作品!!!

注:博主将坚持每月上线一个新app!!!

目录:[Swift]通天遁地Swift

本文将演示如何使用第三方类库,快速实现多种的加密算法。

首先确保已经安装了所需的第三方类库,点击查看配置文件。

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.
    }
}