字符串的加密與解密(3DES、sha1、MD5) - swift3.1

對于字符串的加密解密,可以給String類擴展方法,方便使用

Swift中使用3DES/sha1/MD5加密解密算法 必須要引入這個庫 - 在橋接文件中
#import <CommonCrypto/CommonCrypto.h>

3DES的加密是可逆的, sha1和MD5的是不可逆的

extension String {

    /**
     3DES的加密過程 和 解密過程

     - parameter op : CCOperation: 加密還是解密
     CCOperation(kCCEncrypt)加密
     CCOperation(kCCDecrypt) 解密

     - parameter key: 專有的key,一個鑰匙一般
     - parameter iv : 可選的初始化向量,可以為nil
     - returns      : 返回加密或解密的參數(shù)
     */
    func threeDESEncryptOrDecrypt(op: CCOperation,key: String,iv: String) -> String? {

        // Key
        let keyData: NSData = (key as NSString).data(using: String.Encoding.utf8.rawValue) as NSData!
        let keyBytes         = UnsafeMutableRawPointer(mutating: keyData.bytes)

        // 加密或解密的內容
        var data: NSData = NSData()
        if op == CCOperation(kCCEncrypt) {
            data  = (self as NSString).data(using: String.Encoding.utf8.rawValue) as NSData!
        }
        else {
            data =  NSData(base64Encoded: self, options: NSData.Base64DecodingOptions.ignoreUnknownCharacters)!
        }

        let dataLength    = size_t(data.length)
        let dataBytes     = UnsafeMutableRawPointer(mutating: data.bytes)

        // 返回數(shù)據(jù)
        let cryptData    = NSMutableData(length: Int(dataLength) + kCCBlockSize3DES)
        let cryptPointer = UnsafeMutableRawPointer(cryptData!.mutableBytes)
        let cryptLength  = size_t(cryptData!.length)

        //  可選 的初始化向量
        let viData :NSData = (iv as NSString).data(using: String.Encoding.utf8.rawValue) as NSData!
        let viDataBytes    = UnsafeMutableRawPointer(mutating: viData.bytes)

        // 特定的幾個參數(shù)
        let keyLength              = size_t(kCCKeySize3DES)
        let operation: CCOperation = UInt32(op)
        let algoritm:  CCAlgorithm = UInt32(kCCAlgorithm3DES)
        let options:   CCOptions   = UInt32(kCCOptionPKCS7Padding)

        var numBytesCrypted :size_t = 0

        let cryptStatus = CCCrypt(operation, // 加密還是解密
            algoritm, // 算法類型
            options,  // 密碼塊的設置選項
            keyBytes, // 秘鑰的字節(jié)
            keyLength, // 秘鑰的長度
            viDataBytes, // 可選初始化向量的字節(jié)
            dataBytes, // 加解密內容的字節(jié)
            dataLength, // 加解密內容的長度
            cryptPointer, // output data buffer
            cryptLength,  // output data length available
            &numBytesCrypted) // real output data length



        if UInt32(cryptStatus) == UInt32(kCCSuccess) {

            cryptData!.length = Int(numBytesCrypted)
            if op == CCOperation(kCCEncrypt)  {
                let base64cryptString = cryptData?.base64EncodedString(options: .lineLength64Characters)
                return base64cryptString
            }
            else {
                //   let base64cryptString = NSString(bytes: cryptPointer, length: cryptLength, encoding: NSUTF8StringEncoding) as? String  // 用這個會導致返回的JSON數(shù)據(jù)格式可能有問題,最好不用
                let base64cryptString = NSString(data: cryptData! as Data,  encoding: String.Encoding.utf8.rawValue) as? String
                return base64cryptString
            }
        } else {
            print("Error: \(cryptStatus)")
        }
        return nil
    }


    /*sha1不可逆加密**/
    func sha1() -> String {
        let data = self.data(using: String.Encoding.utf8)!
        var digest = [UInt8](repeating: 0, count:Int(CC_SHA1_DIGEST_LENGTH))
        data.withUnsafeBytes {
            _ = CC_SHA1($0, CC_LONG(data.count), &digest)
        }
        let hexBytes = digest.map { String(format: "%02hhx", $0) }
        return hexBytes.joined()
    }


    func MD5() -> String {
        let str = self.cString(using: String.Encoding.utf8)
        let strLen = CUnsignedInt(self.lengthOfBytes(using: String.Encoding.utf8))
        let digestLen = Int(CC_MD5_DIGEST_LENGTH)
        let result = UnsafeMutablePointer<CUnsignedChar>.allocate(capacity: digestLen)
        //        let result = UnsafeMutablePointer<CUnsignedChar>.init(allocatingCapacity: digestLen)
        CC_MD5(str!, strLen, result)
        let hash = NSMutableString()
        for i in 0 ..< digestLen {
            hash.appendFormat("%02x", result[i])
        }
        result.deinitialize()

        return String(format: hash as String)
    }

}

使用方法:
直接在xib界面拖一個textFiled的控件,然后放置3個按鈕,分別是進行MD5、sha1、3DES加密點擊方法,然后分別測試加密解密數(shù)據(jù)

  //3DES
    @IBAction func desButtonClick(_ sender: UIButton) {
        let keyStr = "ns@$65ds$%^^vdiefif934I&^%#46gn1a"
        print("----原密碼---**\(tf.text)**")

        /**
         3DES的加密過程 和 解密過程

         - parameter op : CCOperation: 加密還是解密
         CCOperation(kCCEncrypt)加密
         CCOperation(kCCDecrypt) 解密

         - parameter key: 專有的key,一個鑰匙一般
         - parameter iv : 可選的初始化向量,可以為nil
         - returns      : 返回加密或解密的參數(shù)
         */

        let mi_string = tf.text?.threeDESEncryptOrDecrypt(op: CCOperation(kCCEncrypt), key: keyStr, iv: "")
        print("--加密--mi_string----***\(mi_string)**")

        let ming_string = mi_string?.threeDESEncryptOrDecrypt(op: CCOperation(kCCDecrypt), key: keyStr, iv: "")
        print("--解密--ming_string----***\(ming_string)**")
    }
    
  //sha1
    @IBAction func sha1ButtonClick(_ sender: UIButton) {
        self.view.endEditing(true)
        print("---sha1加密---**\(tf.text)")

        let psw_sha1 = tf.text?.sha1()
        print("---psw_sha1- 加密后的字符串 *****----****\(psw_sha1)")
    }

  //MD5
    @IBAction func MD5ButtonClick(_ sender: UIButton) {
        self.view.endEditing(true)
        print("---MD5加密---**\(tf.text)")

        let psw_MD5 = tf.text?.MD5()
        print("---psw_MD5- 加密后的字符串 *****----****\(psw_MD5)")
    }
重點問題: 如果遇到3DES解密與java后臺的不符合或者解密不成功的情況,可能的原因是需要使用3DES+base64進行加密解密

可以參考文章http://www.cnblogs.com/jukaiit/p/5039803.html
使用這個第三方來實現(xiàn) JKEncrypt
** https://github.com/jukai9316/JKEncrypt。**

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

  • 本文主要介紹移動端的加解密算法的分類、其優(yōu)缺點特性及應用,幫助讀者由淺入深地了解和選擇加解密算法。文中會包含算法的...
    蘋果粉閱讀 11,678評論 5 29
  • 概述 之前一直對加密相關的算法知之甚少,只知道類似DES、RSA等加密算法能對數(shù)據(jù)傳輸進行加密,且各種加密算法各有...
    Henryzhu閱讀 3,218評論 0 14
  • 隨著對于安全度的不斷要求,對于數(shù)據(jù)加解密與破解之間的斗爭,加解密的方式也在不斷發(fā)生著變化,來看看現(xiàn)在流行的一些加解...
    zhouhao_180閱讀 2,228評論 1 12
  • 沒有一種行為 像長大必須來臨 更令人怔忡 鏡中聚增的須髭 肆意飛揚 成切膚之痛 . 砸碎了的目光轍痕 逃向時空的最...
    周延龍閱讀 259評論 0 4
  • 道德經上善若水的意思包含了很多層。題目設計的很好。
    安然見南山閱讀 244評論 0 2

友情鏈接更多精彩內容