HMAC SHA512 using CommonCrypto in Swift 3.1 [duplicate]

筅森魡賤 提交于 2019-12-06 14:58:34

问题


I'm trying to encrypt data to send to the API.

The API requires the data to be sent as hmac_sha512 encrypted hash.

I've found various examples of how it possibly could have been done for sha1 and others (not sha512) and also in older versions of Swift.

None of the examples that I tried work for swift 3.1

Any help in the right direction will be appreciated.

Edit:

In PHP, I successfully send it using:

    $sign = hash_hmac('sha512', $post_data, $this->secret);

Edit 2:

I did add briding header, I don't know what to do next! As the code examples followed after that don't work for swift 3.1 :(

Edit 3:

Solved! Guess what, I was creating briding header incorrectly! :(

P.S I'm trying to avoid CryptoSwift, focusing on CommonCrypto.

The answer given below is not proper, as it doesn't allow hmac to get a key for encryption. I did research and finally got it working. This post contains the working example project for hmac: https://github.com/nabtron/hmacTest


回答1:


I think the best thing to do is using Crypto pod which is a wrapper for common crypto. In case you want to use directly commonCrypto you should add the bridging header to the project and import common crypto using: #import <CommonCrypto/CommonCrypto.h>

Edit 1

Create a swift class and add the following code to it:

import Foundation

extension String {
    var md5: String {
        return HMAC.hash(inp: self, algo: HMACAlgo.MD5)
    }

    var sha1: String {
        return HMAC.hash(inp: self, algo: HMACAlgo.SHA1)
    }

    var sha224: String {
        return HMAC.hash(inp: self, algo: HMACAlgo.SHA224)
    }

    var sha256: String {
        return HMAC.hash(inp: self, algo: HMACAlgo.SHA256)
    }

    var sha384: String {
        return HMAC.hash(inp: self, algo: HMACAlgo.SHA384)
    }

    var sha512: String {
        return HMAC.hash(inp: self, algo: HMACAlgo.SHA512)
    }
}

public struct HMAC {

    static func hash(inp: String, algo: HMACAlgo) -> String {
        if let stringData = inp.data(using: String.Encoding.utf8, allowLossyConversion: false) {
            return hexStringFromData(input: digest(input: stringData as NSData, algo: algo))
        }
        return ""
    }

    private static func digest(input : NSData, algo: HMACAlgo) -> NSData {
        let digestLength = algo.digestLength()
        var hash = [UInt8](repeating: 0, count: digestLength)
        switch algo {
        case .MD5:
            CC_MD5(input.bytes, UInt32(input.length), &hash)
            break
        case .SHA1:
            CC_SHA1(input.bytes, UInt32(input.length), &hash)
            break
        case .SHA224:
            CC_SHA224(input.bytes, UInt32(input.length), &hash)
            break
        case .SHA256:
            CC_SHA256(input.bytes, UInt32(input.length), &hash)
            break
        case .SHA384:
            CC_SHA384(input.bytes, UInt32(input.length), &hash)
            break
        case .SHA512:
            CC_SHA512(input.bytes, UInt32(input.length), &hash)
            break
        }
        return NSData(bytes: hash, length: digestLength)
    }

    private static func hexStringFromData(input: NSData) -> String {
        var bytes = [UInt8](repeating: 0, count: input.length)
        input.getBytes(&bytes, length: input.length)

        var hexString = ""
        for byte in bytes {
            hexString += String(format:"%02x", UInt8(byte))
        }

        return hexString
    }
}

enum HMACAlgo {
    case MD5, SHA1, SHA224, SHA256, SHA384, SHA512

    func digestLength() -> Int {
        var result: CInt = 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)
    }
}

then use it simply by stringName.sha512
this class extends the String class which gives the ability to use the hashing as a function in the string class.



来源:https://stackoverflow.com/questions/44420192/hmac-sha512-using-commoncrypto-in-swift-3-1

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!