1

I want to transform this JavaScript HMAC code to Swift using CryptoSwift library.

var crypto = require("crypto");
var currentDate = Moment.utc().format("YYYYMMDDHH");
var hmac = crypto.createHmac("sha256", "secretTokenKey123");
hmac.update(currentDate);
var code = hmac.digest("hex").toUpperCase();

What is the best way to do that?

This is what I tried, but did not return the correct code:

    let formatter = DateFormatter()
    formatter.dateFormat = "yyyyMMddHH"
    let dateString = formatter.string(from: Date())
    let baseString = secretToken + dateString
    print(baseString.sha256().uppercased())

I also tried this, but it returns the same wrong code

    var digest = SHA2(variant: .sha256)
    var bytes: Array<UInt8>?
    do {
        _ = try digest.update(withBytes: secretToken.bytes)
        _ = try digest.update(withBytes: dateString.bytes)
        bytes = try digest.finish()
    } catch {}
    if let result = bytes?.toHexString().uppercased() {
        print(result)
    }

I also tried to use HMCA from CryptoSwift directly. But I do not know what message I need to authenticate:

HMAC(key: secretToken.bytes, variant: .sha256).authenticate(???)
jww
  • 97,681
  • 90
  • 411
  • 885
funkenstrahlen
  • 3,032
  • 2
  • 28
  • 40
  • I tried to use `try HMAC(key: key, variant: .sha256).authenticate(bytes)` from `CryptoSwift`. However it does not match how it is used in my JS example. I do not have something to put in as `bytes`. – funkenstrahlen Dec 23 '17 at 11:16
  • @Andreas I updated my question to show what I already tried without the correct result. – funkenstrahlen Dec 23 '17 at 11:40
  • It is best to avoid using CryptoSwift, amoung other things it is 500 to 1000 times slower than Common Crypto based implementations. Apple's Common Crypto is FIPS certified and as such has been well vetted, using CryptoSwift is taking a chance on correctness and security. – zaph Dec 23 '17 at 13:01
  • @zaph Can you tell me how to implement this using Apple's Common Crypto? – funkenstrahlen Dec 28 '17 at 10:58

2 Answers2

2

I just discovered the solution myself:

HMAC(key: secretToken.bytes, variant: .sha256).authenticate(dateString.bytes).toHexString().uppercased()
funkenstrahlen
  • 3,032
  • 2
  • 28
  • 40
0

HAMC SHA256 in Common Crypto

func hmacSHA256(message:Data, key:Data) -> Data {
    var macData = Data(count: Int(CC_SHA256_DIGEST_LENGTH))

    macData.withUnsafeMutableBytes {macBytes in
        message.withUnsafeBytes {messageBytes in
            key.withUnsafeBytes {keyBytes in
                CCHmac(CCHmacAlgorithm(kCCHmacAlgSHA256),
                       keyBytes,     key.count,
                       messageBytes, message.count,
                       macBytes)
            }
        }
    }
    return macData
}

let clearData = "clearData0123456".data(using:.utf8)!
let keyData   = "keyData8901234562".data(using:.utf8)!
let hmacData  = hmacSHA256(message:clearData, key:keyData)
print("hmacData: \(String(describing: hmacData as NSData))")

hmacData: fcc487ce7dc1115a69a37dc3710610a87ad2fc9c85e2e0a52f0e7ee1dc9407c1

Note:
Include #import <CommonCrypto/CommonCrypto.h> in a bridging header.
Add Security.framework to the project

zaph
  • 111,848
  • 21
  • 189
  • 228