zoukankan      html  css  js  c++  java
  • [Swift通天遁地]七、数据与安全-(17)使用Swift实现原生的3DES加密和解密

    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
    ➤微信公众号:山青咏芝(shanqingyongzhi)
    ➤博客园地址:山青咏芝(https://www.cnblogs.com/strengthen/
    ➤GitHub地址:https://github.com/strengthen/LeetCode
    ➤原文地址:https://www.cnblogs.com/strengthen/p/10346852.html 
    ➤如果链接不是山青咏芝的博客园地址,则可能是爬取作者的文章。
    ➤原文已修改更新!强烈建议点击原文地址阅读!支持作者!支持原创!
    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★

    目录:[Swift]通天遁地Swift

    本文将演示如何编写原生的3DES加密和解密程序。

    首先创建一个桥接头文件,因为需要使用到OC语言的通用加密解密类库。

    在项目文件夹【DemoApp】上点击鼠标右键,弹出右键菜单。

    【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】,显示项目的属性信息,

    将头文件添加到桥接头选项中->【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 }
  • 相关阅读:
    CSS实例:图片导航块
    导航,头部,CSS基础
    web基础,用html元素制作web页面
    web基础
    timestamp与timedelta,管理信息系统概念与基础
    datetime处理日期和时间
    中文词频统计
    文件方式实现完整的英文词频统计实例
    当你发现任务管理器打不开
    恶搞关机
  • 原文地址:https://www.cnblogs.com/strengthen/p/10346852.html
Copyright © 2011-2022 走看看