Post

Swift进行AES加解密之使用CryptoSwift、CommonCrypto耗时相差300倍

参考:

一、使用CryptoSwift进行AES加解密的代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import Foundation
import CryptoSwift

class AESTool1 {
    static func AESEncrypt(key: String?, data: Data?) -> Data? {
        return AESCrypt(isEncode: true, key: key?.data(using: .utf8), data: data)
    }
    
    static func AESDecrypt(key: String?, data: Data?) -> Data? {
        return AESCrypt(isEncode: false, key: key?.data(using: .utf8), data: data)
    }
    
    static func AESCrypt(isEncode: Bool, key: Data?, data: Data?) -> Data? {
        guard let data = data, data.count > 0 else { return nil }
        guard let key = key, key.count > 0 else { return nil }
        do {
            if isEncode == false {
                // 解密
                let deBytes = try AES(key: key.bytes, blockMode: ECB(), padding: .pkcs5).decrypt(data.bytes)
                return Data(deBytes)
            } else {
                // 加密
                let enBytes = try AES(key: key.bytes, blockMode: ECB(), padding: .pkcs5).encrypt(data.bytes)
                return Data(enBytes)
            }
        } catch let error {
            print("decodeAES--data: \(error)")
        }
        return nil
    }
}
二、使用系统库CommonCrypto进行加解密的方式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
import Foundation
import CommonCrypto

class AESTool2 {
    static func AESEncrypt(key: String?, data: Data?) -> Data? {
        return AESCrypt(isEncode: true, key: key?.data(using: .utf8), data: data)
    }
    
    static func AESDecrypt(key: String?, data: Data?) -> Data? {
        return AESCrypt(isEncode: false, key: key?.data(using: .utf8), data: data)
    }
    
    static func AESCrypt(isEncode: Bool, key: Data?, data: Data?) -> Data? {
        guard let data = data, data.count > 0 else { return nil }
        guard let key = key, key.count > 0 else { return nil }
        
        let op = isEncode ? CCOperation(kCCEncrypt) : CCOperation(kCCDecrypt)
        let keyLength = kCCKeySizeAES128
        let cryptLength = data.count + kCCBlockSizeAES128
        var cryptData = Data(count: cryptLength)
        var numBytesEncrypted: Int = 0
        
        let cryptStatus = cryptData.withUnsafeMutableBytes { cryptBytes in
            data.withUnsafeBytes { dataBytes in
                key.withUnsafeBytes { keyBytes in
                    CCCrypt(op,
                            CCAlgorithm(kCCAlgorithmAES),
                            CCOptions(kCCOptionECBMode + kCCOptionPKCS7Padding),
                            keyBytes.baseAddress, keyLength,
                            nil,
                            dataBytes.baseAddress, data.count,
                            cryptBytes.baseAddress, cryptLength,
                            &numBytesEncrypted)
                }
            }
        }
        
        if cryptStatus == kCCSuccess {
            cryptData.removeSubrange(numBytesEncrypted..<cryptData.count)
            return cryptData
        }
        return nil
    }
}

三、测试CryptoSwiftCommonCrypto,结果差异接近300倍
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        DispatchQueue.global().async { [weak self] in
            guard let self = self else {
                return
            }
            let (dis1, dis2, dis3) = self.testAES1()
            let (dis12, dis22, dis32) = self.testAES2()
            print("CryptoSwift与CommonCrypto效率:加密效率:\(dis1/dis12) 解密效率:\(dis2/dis22) 加解密效率:\(dis3/dis32)")
        }
       
    }
    
    func testAES1() -> (Double, Double, Double) {
        let startDate1 = Date().timeIntervalSince1970
        let originStr = "阿里斯顿减肥啦上岛咖啡进啦手打飞机萨达"
        let key = "abcdef1234567890" // 16位
        let repeatCount = 999
        for idx in 0..<repeatCount {
            let encodeData = AESTool1.AESEncrypt(key: key, data: originStr.data(using: .utf8))
            if (encodeData?.count ?? 0) == 0 {
                print("CryptoSwift idx: \(idx) encodeData:\(encodeData?.count ?? 0) 加密失败")
            }
        }
        let endDate1 = Date().timeIntervalSince1970
        let distance1 = endDate1-startDate1
        print("CryptoSwift 加密\(repeatCount)次 耗时:\(distance1)")
        
        let encodeData2 = AESTool1.AESEncrypt(key: key, data: originStr.data(using: .utf8))
        let startDate2 = Date().timeIntervalSince1970
        for idx in 0...repeatCount {
            let decodeData = AESTool1.AESDecrypt(key: key, data: encodeData2)
            var decodeStr: String? = nil
            if let data = decodeData {
                decodeStr = String(data: data, encoding: .utf8)
            }
            if (decodeData?.count ?? 0) == 0 || decodeStr == nil {
                print("CryptoSwift idx: \(idx) encodeData:\(decodeData?.count ?? 0) 解密失败")
            }
        }
        let endDate2 = Date().timeIntervalSince1970
        let distance2 = endDate2-startDate2
        print("CryptoSwift 解密\(repeatCount)次 耗时:\(distance2)")
        
        let startDate3 = Date().timeIntervalSince1970
        for idx in 0...repeatCount {
            
            let encodeData = AESTool1.AESEncrypt(key: key, data: originStr.data(using: .utf8))
            let decodeData = AESTool1.AESDecrypt(key: key, data: encodeData)
            var decodeStr: String? = nil
            if let data = decodeData {
                decodeStr = String(data: data, encoding: .utf8)
                
            }
            if (encodeData?.count ?? 0) == 0 || (decodeData?.count ?? 0) == 0 || decodeStr == nil {
                print("CryptoSwift idx: \(idx) encodeData:\(encodeData?.count ?? 0) decodeData:\(decodeData?.count ?? 0) decodeStr:\(decodeStr ?? "加解密失败")")
            }
        }
        let endDate3 = Date().timeIntervalSince1970
        let distance3 = endDate3-startDate3
        print("CryptoSwift 加解密\(repeatCount)次 耗时:\(distance3)")
        return (distance1, distance2, distance3)
    }
    func testAES2() -> (Double, Double, Double) {
        let startDate1 = Date().timeIntervalSince1970
        let originStr = "阿里斯顿减肥啦上岛咖啡进啦手打飞机萨达"
        let key = "abcdef1234567890" // 16位
        let repeatCount = 999
        for idx in 0..<repeatCount {
            let encodeData = AESTool2.AESEncrypt(key: key, data: originStr.data(using: .utf8))
            if (encodeData?.count ?? 0) == 0 {
                print("CommonCrypto idx: \(idx) encodeData:\(encodeData?.count ?? 0) 加密失败")
            }
        }
        let endDate1 = Date().timeIntervalSince1970
        let distance1 = endDate1-startDate1
        print("CommonCrypto 加密\(repeatCount)次 耗时:\(distance1)")
        
        let encodeData2 = AESTool2.AESEncrypt(key: key, data: originStr.data(using: .utf8))
        let startDate2 = Date().timeIntervalSince1970
        for idx in 0...repeatCount {
            let decodeData = AESTool2.AESDecrypt(key: key, data: encodeData2)
            var decodeStr: String? = nil
            if let data = decodeData {
                decodeStr = String(data: data, encoding: .utf8)
            }
            if (decodeData?.count ?? 0) == 0 || decodeStr == nil {
                print("CommonCrypto idx: \(idx) encodeData:\(decodeData?.count ?? 0) 解密失败")
            }
        }
        let endDate2 = Date().timeIntervalSince1970
        let distance2 = endDate2-startDate2
        print("CommonCrypto 解密\(repeatCount)次 耗时:\(distance2)")
        
        let startDate3 = Date().timeIntervalSince1970
        for idx in 0...repeatCount {
            
            let encodeData = AESTool2.AESEncrypt(key: key, data: originStr.data(using: .utf8))
            let decodeData = AESTool2.AESDecrypt(key: key, data: encodeData)
            var decodeStr: String? = nil
            if let data = decodeData {
                decodeStr = String(data: data, encoding: .utf8)
                
            }
            if (encodeData?.count ?? 0) == 0 || (decodeData?.count ?? 0) == 0 || decodeStr == nil {
                print("CommonCrypto idx: \(idx) encodeData:\(encodeData?.count ?? 0) decodeData:\(decodeData?.count ?? 0) decodeStr:\(decodeStr ?? "加解密失败")")
            }
        }
        let endDate3 = Date().timeIntervalSince1970
        let distance3 = endDate3-startDate3
        print("CommonCrypto 加解密\(repeatCount)次 耗时:\(distance3)")
        return (distance1, distance2, distance3)
    }

}
/**
CryptoSwift 加密999次 耗时:0.4818587303161621
CryptoSwift 解密999次 耗时:0.4647197723388672
CryptoSwift 加解密999次 耗时:0.9191689491271973
CommonCrypto 加密999次 耗时:0.0016758441925048828
CommonCrypto 解密999次 耗时:0.0015459060668945312
CommonCrypto 加解密999次 耗时:0.0029468536376953125
CryptoSwift与CommonCrypto效率:加密效率:287.5319391094039 解密效率:300.6132017273288 加解密效率:311.91537216828476
*/
This post is licensed under CC BY 4.0 by the author.