[Swift通天遁地]7、數據與安全-(17)使用Swift實現原生的3DES加密和解密

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

目錄:[Swift]通天遁地Swiftgit

本文將演示如何編寫原生的3DES加密和解密程序。github

首先建立一個橋接頭文件,由於須要使用到OC語言的通用加密解密類庫。算法

在項目文件夾【DemoApp】上點擊鼠標右鍵,彈出右鍵菜單。swift

【New File】->【Header File】->【Next】->緩存

【Save As】:Header.h->【Create】安全

在該文件中,添加須要引用到的框架。微信

1 //添加須要引用到的框架。
2 #ifndef Header_h
3 #define Header_h
4 
5 #import <CommonCrypto/CommonCrypto.h>
6 #import "SecurityUtil.h"
7 
8 #endif /* Header_h */

點擊項目名稱【DemoApp】,顯示項目的屬性信息,app

將頭文件添加到橋接頭選項中->【Build Settings】框架

->在搜索框內,輸入須要定位的設置項目的名稱:【Objective-C Bridging Hader】

->鼠標雙擊選項右側【Objective-C Bridging Hader】,彈出橋接頭文件設置窗口。

->在打開的輸入窗口中,輸入剛剛建立的頭文件的相對路徑:【DemoApp/Header.h】

在項目導航區,打開視圖控制器的代碼文件【ViewController.swift】

如今開始編寫代碼,實現3DES的加密和解密功能。

  1 import UIKit
  2 
  3 //首先建立一個集合,用來生成隨機的公用的密鑰
  4 private let randomStringArray: [Character] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789".map({$0})
  5 
  6 class ViewController: UIViewController {
  7     
  8     //給類添加一個字符串屬性,
  9     //做爲加密解密的公鑰和私鑰,
 10     //並對其進行初始化操做。
 11     var key:String = ""
 12     
 13     override func viewDidLoad() {
 14         super.viewDidLoad()
 15         // Do any additional setup after loading the view, typically from a nib.
 16         //調用方法
 17         encrypt(encryptData: "https://www.cnblogs.com/strengthen/")
 18     }
 19     
 20     //添加一個方法,用來生成指定長度的字符串
 21     func randomStringOfLength(_ length:Int) -> String
 22     {
 23         //初始化一個字符串變量
 24         var string = ""
 25         //添加一個指定次數的循環語句
 26         ////往字符串變量中添加隨機的字符
 27         for _ in (1...length)
 28         {            
 29             //從集合中得到英文大小寫字母和0~9之間的隨機數字,
 30             //並將隨機字符添加到字符串中。
 31             string.append(randomStringArray[Int(arc4random_uniform(UInt32(randomStringArray.count) - 1))])
 32         }
 33         //返回生成的隨機字符串
 34         return string
 35     }
 36     
 37     //添加一個方法,對字符串參數進行加密
 38     func encrypt(encryptData:String)
 39     {
 40         //生成一個隨機的字符串,做爲加密解密的密鑰。
 41         //其參數的值是24,
 42         //所以這裏將生成一個長度爲24的,包含英文大小寫字母和數字的隨機字符串。
 43         key = randomStringOfLength(kCCKeySize3DES)
 44         //將待加密的字符串,轉換成指定編碼的數據類型。
 45         let inputData : Data = encryptData.data(using: String.Encoding.utf8)!
 46         //將隨機字符串的密鑰,一樣轉換成數據類型。
 47         let keyData: Data = key.data(using: String.Encoding.utf8, allowLossyConversion: false)!
 48         //建立一個非安全的可變原始指針,
 49         //在建立該指針時,向系統申請了個數爲密鑰字節數的內存。
 50         let keyBytes = UnsafeMutableRawPointer(mutating: (keyData as NSData).bytes)
 51         //建立一個常量,表示密鑰的長度,它的值是24
 52         let keyLength = size_t(kCCKeySize3DES)
 53         //得到待加密的數據類型對象的長度。
 54         let dataLength = Int(inputData.count)
 55         //建立一個非安全的指針,並從系統中分配相應的內存,做爲加密的輸入緩存。
 56         let dataBytes = UnsafeRawPointer((inputData as NSData).bytes)
 57         //建立一個指定長度的可變二進制數據對象,
 58         //該對象做爲加密的輸出緩存,用來存儲加密後的數據。
 59         //其長度爲輸入緩存的長度和塊大小的和,塊的大小爲8。
 60         let bufferData = NSMutableData(length: Int(dataLength) + kCCBlockSize3DES)!
 61         //建立一個非安全的可變指針,並根據輸出緩存的大小,分配相應的內存。
 62         let bufferPointer = UnsafeMutableRawPointer(bufferData.mutableBytes)
 63         //得到輸出緩存的長度。
 64         let bufferLength = size_t(bufferData.length)
 65         //建立一個變量,用來存儲加密後的輸出緩存的最終字節數。
 66         var bytesDecrypted = Int(0)
 67         
 68         //調用來自頭文件中的加密解密方法,
 69         //參數1:用來區分加密或解密,這裏選擇加密
 70         //參數2:加密的算法
 71         //參數3:使用密鑰和算法,對文本進行加密時的方法。
 72         let cryptStatus = CCCrypt(UInt32(kCCEncrypt), UInt32(kCCAlgorithm3DES),
 73                                   UInt32(kCCOptionECBMode + kCCOptionPKCS7Padding),
 74                                   keyBytes, keyLength, nil, dataBytes, dataLength,
 75                                   bufferPointer, bufferLength, &bytesDecrypted)
 76         
 77         //當執行完加密方法後,會返回一個狀態,經過對狀態的檢測,
 78         //能夠判斷加密操做是否成功,
 79         //加密操做有可能返回七種狀態。
 80         if Int32(cryptStatus) == Int32(kCCSuccess)
 81         {
 82             //當判斷加密操做正確後,設置輸出數據的長度,
 83             //以調整輸出緩存的大小。爲最終輸出的加密數據的長度。
 84             bufferData.length = bytesDecrypted
 85             
 86             //在控制檯輸出日誌
 87             print(bufferData)
 88             //對加密後的數據進行解密。
 89             decrypt(inputData: bufferData as Data)
 90         }
 91         else
 92         {
 93             print("Error:\(cryptStatus)")
 94         }
 95     }
 96     
 97     //添加一個方法,用來實現指定類型的解密操做。
 98     //解密的代碼和加密的代碼大體相同
 99     func decrypt(inputData : Data)
100     {
101         //將做爲隨機字符串的密鑰,轉換成數據類型
102         let keyData: Data = key.data(using: String.Encoding.utf8, allowLossyConversion: false)!
103         //建立一個非安全的可變原始指針,
104         //在建立該指針時,向系統申請了個數爲密鑰字節數的內存。
105         let keyBytes       = UnsafeMutableRawPointer(mutating: (keyData as NSData).bytes)
106         //建立一個常量,表示密鑰的長度,它的值是 24
107         let keyLength      = size_t(kCCKeySize3DES)
108         //得到待加密數據類型對象的長度
109         let dataLength     = Int(inputData.count)
110         //建立一個非安全的指針,並從系統中分配相應的內存,做爲解密的輸入緩存。
111         let dataBytes      = UnsafeRawPointer((inputData as NSData).bytes)
112         //建立一個指定長度的可變二進制數據對象,
113         //該對象做爲解密的輸出緩存,用來存儲解密後的數據。
114         //其長度爲輸入緩存的長度和塊大小的和,塊的大小爲8。
115         let bufferData     = NSMutableData(length: Int(dataLength) + kCCBlockSize3DES)!
116         //建立一個非安全的可變指針,並根據輸出緩存的大小,分配相應的內存。
117         let bufferPointer  = UnsafeMutableRawPointer(bufferData.mutableBytes)
118         //得到輸出緩存的長度
119         let bufferLength   = size_t(bufferData.length)
120         //建立一個變量,用來存儲解密後的輸出緩存的最終字節數。
121         var bytesDecrypted = Int(0)
122         
123         //調用來自頭文件中的加密解密方法,
124         //參數1:用來區分加密或解密,這裏選擇解密
125         //參數2:解密的算法
126         //參數3:使用密鑰和算法,對文本進行解密時的方法。
127         let cryptStatus = CCCrypt(UInt32(kCCDecrypt), UInt32(kCCAlgorithm3DES),
128                                   UInt32(kCCOptionECBMode + kCCOptionPKCS7Padding),
129                                   keyBytes, keyLength, nil, dataBytes, dataLength,
130                                   bufferPointer, bufferLength, &bytesDecrypted)
131         
132         //當執行完加密方法後,會返回一個狀態,經過對狀態的檢測,
133         //能夠判斷解密操做是否成功,
134         if Int32(cryptStatus) == Int32(kCCSuccess)
135         {
136             //當判斷解密操做正確後,設置輸出數據的長度,
137             //以調整輸出緩存的大小。爲最終輸出的解密數據的長度。
138             bufferData.length = bytesDecrypted
139             
140             //將解密後的數據,以指定的編碼方式,轉換成字符串對象。
141             let clearDataAsString = NSString(data: bufferData as Data, encoding: String.Encoding.utf8.rawValue)
142             //打印日誌
143             print("The result:\(clearDataAsString! as String)")
144         }
145         else
146         {
147             //打印日誌
148             print("Error in crypto operation:\(cryptStatus)")
149         }
150     }
151     
152     override func didReceiveMemoryWarning() {
153         super.didReceiveMemoryWarning()
154         // Dispose of any resources that can be recreated.
155     }
156 }
相關文章
相關標籤/搜索