美文网首页
【实践】Swift3 封装加密工具类CryptoHelper

【实践】Swift3 封装加密工具类CryptoHelper

作者: SmartisanBool | 来源:发表于2017-05-16 16:25 被阅读65次

    使用OC的CommonCrypto库完成对swift的加密/解密工具类的封装。支持散列哈希(MD5, SHA1, SHA224, SHA256, SHA384, SHA512)及AES加密

    1.引入CommonCrypto库

    #import <CommonCrypto/CommonHMAC.h>
    #import <CommonCrypto/CommonDigest.h>
    #import <CommonCrypto/CommonCryptor.h>
    

    2.创建CryptoAlgorithm枚举

    enum CryptoAlgorithm{
    
        case MD5, SHA1, SHA224, SHA256, SHA384, SHA512
    
        var HMACAlgorithm: CCHmacAlgorithm {
            var result: Int = 0
            switch self {
                case .MD5:      result = kCCHmacAlgMD5
                case .SHA1:     result = kCCHmacAlgSHA1
                case .SHA224:   result = kCCHmacAlgSHA224
                case .SHA256:   result = kCCHmacAlgSHA256
                case .SHA384:   result = kCCHmacAlgSHA384
                case .SHA512:   result = kCCHmacAlgSHA512
            }
            return CCHmacAlgorithm(result)
        }
    
        var digestLength: Int {
            var result: Int32 = 0
            switch self {
                case .MD5:      result = CC_MD5_DIGEST_LENGTH
                case .SHA1:     result = CC_SHA1_DIGEST_LENGTH
                case .SHA224:   result = CC_SHA224_DIGEST_LENGTH
                case .SHA256:   result = CC_SHA256_DIGEST_LENGTH
                case .SHA384:   result = CC_SHA384_DIGEST_LENGTH
                case .SHA512:   result = CC_SHA512_DIGEST_LENGTH
            }
            return Int(result)
        }
    }
    

    3.创建String扩展

    extension String{
    
        var md5 : String!{
            let str = self.cString(using: String.Encoding.utf8)
            let strLen = CC_LONG(self.lengthOfBytes(using: String.Encoding.utf8))
            let digestLen = Int(CC_MD5_DIGEST_LENGTH)
            let result = UnsafeMutablePointer<CUnsignedChar>.allocate(capacity: digestLen)
            CC_MD5(str!, strLen, result)
            return stringFromBytes(bytes: result, length: digestLen)
        }
    
    
        var sha1: String! {
            let str = self.cString(using: String.Encoding.utf8)
            let strLen = CC_LONG(self.lengthOfBytes(using: String.Encoding.utf8))
            let digestLen = Int(CC_SHA1_DIGEST_LENGTH)
            let result = UnsafeMutablePointer<CUnsignedChar>.allocate(capacity: digestLen)
            CC_SHA1(str!, strLen, result)
            return stringFromBytes(bytes: result, length: digestLen)
        }
    
    
        var sha256String: String! {
            let str = self.cString(using: String.Encoding.utf8)
            let strLen = CC_LONG(self.lengthOfBytes(using: String.Encoding.utf8))
            let digestLen = Int(CC_SHA256_DIGEST_LENGTH)
            let result = UnsafeMutablePointer<CUnsignedChar>.allocate(capacity: digestLen)
            CC_SHA256(str!, strLen, result)
            return stringFromBytes(bytes: result, length: digestLen)
        }
    
    
        var sha512String: String! {
            let str = self.cString(using: String.Encoding.utf8)
            let strLen = CC_LONG(self.lengthOfBytes(using: String.Encoding.utf8))
            let digestLen = Int(CC_SHA512_DIGEST_LENGTH)
            let result = UnsafeMutablePointer<CUnsignedChar>.allocate(capacity: digestLen)
            CC_SHA512(str!, strLen, result)
            return stringFromBytes(bytes: result, length: digestLen)
        }
    
    
        func stringFromBytes(bytes: UnsafeMutablePointer<CUnsignedChar>, length: Int) -> String{
            let hash = NSMutableString()
            for i in 0..<length {
                hash.appendFormat("%02x", bytes[i])
            }
            bytes.deallocate(capacity: length)
            return String(format: hash as String)
        }
    
        //HMAC 加密
        func hmac(algorithm: CryptoAlgorithm, key: String) -> String {
            let str = self.cString(using: String.Encoding.utf8)
            let strLen = Int(self.lengthOfBytes(using: String.Encoding.utf8))
            let digestLen = algorithm.digestLength
            let result =  UnsafeMutablePointer<CUnsignedChar>.allocate(capacity: digestLen)
            let keyStr = key.cString(using: String.Encoding.utf8)
            let keyLen = Int(key.lengthOfBytes(using: String.Encoding.utf8))
    
            CCHmac(algorithm.HMACAlgorithm, keyStr!, keyLen, str!, strLen, result)
    
            let digest = stringFromResult(result: result, length: digestLen)
    
            result.deallocate(capacity: digestLen)
    
            return digest
        }
    
        //十六进制转换
        private func stringFromResult(result: UnsafeMutablePointer<CUnsignedChar>, length: Int) -> String {
            let hash = NSMutableString()
            for i in 0..<length {
                hash.appendFormat("%02x", result[i])
            }
            return String(hash)
        }
    
        //AES 加密
        func aes(operation: CCOperation,key: String) -> String{
            let keyData             = key.data(using: String.Encoding.utf8)! as NSData
            let keyLen              = Int(kCCKeySizeAES128)
            let keyBytes            = keyData.bytes
    
            let strData             = self.data(using: String.Encoding.utf8)! as NSData
            let dataLen             = strData.length
            let dataBytes           = strData.bytes
    
            let cryptLength         = Int(dataLen + kCCBlockSizeAES128)
            let cryptPointer        = UnsafeMutablePointer<CUnsignedChar>.allocate(capacity: cryptLength)
    
            let algoritm            = CCAlgorithm(kCCAlgorithmAES128)
            let option              = CCOptions(kCCOptionPKCS7Padding|kCCOptionECBMode)
    
            let numBytesEncrypted   = UnsafeMutablePointer<Int>.allocate(capacity: 1)
            numBytesEncrypted.initialize(to: 1)
    
            let cryptStatus         = CCCrypt(operation, algoritm, option, keyBytes, keyLen, nil, dataBytes, dataLen, cryptPointer, cryptLength, numBytesEncrypted)
    
    
            if CCStatus(cryptStatus) == CCStatus(kCCSuccess){
                let len = Int(numBytesEncrypted.pointee)
                let digest = stringFromResult(result: cryptPointer, length: len)
                numBytesEncrypted.deallocate(capacity: 1)
                return digest
            }else{
                return ""
            }
          }
        }
    

    3.测试

        let str = "cyfhaha"
        let aesResult = "814514553e4bc8f7ca3edf9341e81c49"
    
        ALinLog("---------:\(str.hmac(algorithm: .SHA1, key: "chengyanfang"))")
    
        ALinLog("---------:\(str.sha1)")
    
        ALinLog("---------:\(str.aes(operation: CCOperation(kCCEncrypt), key: "chengyanfang"))")
    
        ALinLog("---------:\(aesResult.aes(operation: CCOperation(kCCDecrypt), key: "chengyanfang"))")
    

    打印结果:

      ---------:c792b6aac08880924ece052105cf06d1117789a9
      ---------:3506bc4ecb80abf331b28b0bf18b35aadebe6518
      ---------:814514553e4bc8f7ca3edf9341e81c49
      ---------:cyfhaha

    相关文章

      网友评论

          本文标题:【实践】Swift3 封装加密工具类CryptoHelper

          本文链接:https://www.haomeiwen.com/subject/owvlxxtx.html