0

So this is the original Objective-C code I have:

- (NSString *)calculateSignaturewithAPIKey:(NSString *)apiKey apiKeyPrivate:(NSString *)apiKeyPrivate httpMethod:(NSString *)httpMethod route:(NSString *)theRoute andExpiresIn:(NSString *)expireTime {
    NSString *string_to_sign = [NSString stringWithFormat:@"%@:%@:%@:%@",apiKey,httpMethod,theRoute,expireTime];

    const char *cKey  = [apiKeyPrivate cStringUsingEncoding:NSASCIIStringEncoding];
    const char *cData = [string_to_sign cStringUsingEncoding:NSASCIIStringEncoding];

    unsigned char cHMAC[CC_SHA1_DIGEST_LENGTH];

    CCHmac(kCCHmacAlgSHA1, cKey, strlen(cKey), cData, strlen(cData), cHMAC);

    NSData *HMAC = [[NSData alloc] initWithBytes:cHMAC length:sizeof(cHMAC)];

    NSString *signature = [HMAC base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];
    return signature;
}

In Swift 3 I managed to get as far as:

func calculateSignature(withPublicApiKey publicApiKey: String, andApiPrivateKey privateApiKey: String, withHttpMethod httpMethod: String, andRoute route: String, exiresIn expireTime: String) -> String {
    let string_to_sign = "\(publicApiKey):\(httpMethod):\(route):\(expireTime)"

    let cKey = privateApiKey.cString(using: String.Encoding.ascii)
    let cData = Data.base64EncodedString(Data.init)

    var cHMAC = [CUnsignedChar](repeating: 0, count: Int(CC_SHA1_DIGEST_LENGTH))

But I don't know how to proceed here. I have been able to import Crypto related things into my Swift project. Please assist.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
Dmitri K.
  • 197
  • 1
  • 13
  • 1
    Possible duplicate of [CommonHMAC in Swift](http://stackoverflow.com/questions/24099520/commonhmac-in-swift) – xoudini Dec 20 '16 at 22:35

1 Answers1

0

Try this:

func calculateSignature(withPublicApiKey publicApiKey: String, andApiPrivateKey privateApiKey: String, withHttpMethod httpMethod: String, andRoute route: String, exiresIn expireTime: String) -> String {
    let string_to_sign = "\(publicApiKey):\(httpMethod):\(route):\(expireTime)"
    let cKey = privateApiKey.cString(using: .ascii)!
    let cData = string_to_sign.cString(using: .ascii)!

    var cHMAC = [CUnsignedChar](repeating: 0, count: Int(CC_SHA1_DIGEST_LENGTH))
    CCHmac(CCHmacAlgorithm(kCCHmacAlgSHA1), cKey, cKey.count - 1, cData, cData.count - 1, &cHMAC)

    let HMAC = Data(bytes: &cHMAC, count: Int(CC_SHA1_DIGEST_LENGTH))
    return HMAC.base64EncodedString(options: .lineLength64Characters)
}

My personal experience is that Swift really hates pointers. If you code makes heavy use of pointer, it's easer to write them in C/ObjC.

Code Different
  • 90,614
  • 16
  • 144
  • 163
  • Tried this, even tried to use crypto frameworks on GitHub to achieve this. Basically what happenes is if you put public key to "1234", private key to "abcd", route to "forms/1/entries" httpmethod to "GET" and expire time to "1369749344" it should spit out a string like this uJEnk0EoQ4d3iinjFMBrBzZfH9w= but what swift does with your method and not tryign to say anything bad here, since i got absolutely same result is something like this: "688fdb5f5ce51a298f91aa768391e14dcdbe3ca6" as you can see they are very different. The last resort way for myself is bridge the objective-c into my project. – Dmitri K. Dec 21 '16 at 09:30