Convert Swift? Please?

Could someone be so kind to help me convert this swift to objective c? I'm trying to create a signature for an api and I am having no luck.

Code Block let nonce = Int64(Date().timeIntervalSince1970 * 1000000)
     postdata = "\(serviceRequest)nonce=\(nonce)"
     
     let hash = ("\(nonce)"+postdata).sha256!
     
     let hashData = hash.data(using: .bytesHexLiteral)!
     
     let binaryData = path.data(using: .utf8, allowLossyConversion: false)!
     
     let lenTotal = binaryData.count + hashData.count
     var pathSh256 = Data(capacity: lenTotal)
     for i in 0..<binaryData.count {
     let j = binaryData.index(binaryData.startIndex, offsetBy: i)
     let bytes = binaryData[j]
     pathSh256.append(bytes)
     }
     for i in 0..<(hashData.count) {
     let j = hashData.index((hashData.startIndex), offsetBy: i)
     let bytes = hashData[j]
     pathSh256.append(bytes)
     }
     
     let APISecret = APISecret ?? ""
     let secretDecoded = Data(base64Encoded: APISecret, options: .ignoreUnknownCharacters)!
     let sign = HMAC.sign(data: pathSh256, algorithm: .sha512, key: secretDecoded)
     let apiSign = String(data: (sign.base64EncodedData()),encoding: String.Encoding.utf8)!



What I have so far but it is invalid:

Code Block
NSString *postDataToHashString = [NSString stringWithFormat:@"%@%@", nonce, [NSString stringWithFormat:@"nonce=%@", nonce]];
    const char* utf8chars = [postDataToHashString UTF8String];
    unsigned char result[CC_SHA256_DIGEST_LENGTH];
    CC_SHA256(utf8chars, (CC_LONG)strlen(utf8chars), result);
    NSMutableString *hashString = [NSMutableString stringWithCapacity:CC_SHA256_DIGEST_LENGTH*2];
    for(int i = 0; i<CC_SHA256_DIGEST_LENGTH; i++) {
        [hashString appendFormat:@"%02x",result[i]];
    }
    NSString *dataStringToHmac = [NSString stringWithFormat:@"/0/private/QueryOrders%@", hashString];
    NSData *decodedData = [[NSData alloc] initWithBase64EncodedString:apiSecret options:0];
    NSString *decodedSecret = [[NSString alloc] initWithData:decodedData encoding:NSASCIIStringEncoding];
    NSStringEncoding thisEncoding = NSUTF8StringEncoding;
    uint16_t digest_length[CC_SHA512_DIGEST_LENGTH]={0};
    const char *constantString = [dataStringToHmac cStringUsingEncoding:NSUTF8StringEncoding];
    NSData *stringData = [NSData dataWithBytes:constantString length:strlen(constantString)];
    NSString *key = decodedSecret;
    NSData *keyData = [key dataUsingEncoding:thisEncoding];
    CCHmac(kCCHmacAlgSHA512, keyData.bytes, keyData.length, stringData.bytes, stringData.length, digest_length);
    NSData *hMacHashedData = [NSData dataWithBytes:digest_length length:CC_SHA512_DIGEST_LENGTH];
    NSData *hMacHashData = [[hMacHashedData description] dataUsingEncoding:thisEncoding];
    NSString *hMacHashBase64 = [hMacHashData base64EncodedString];


What it looks like in php:

Code Block if(!isset($request["nonce"])) {
     // generate a 64 bit nonce using a timestamp at microsecond resolution
     // string functions are used to avoid problems on 32 bit systems
     $nonce = explode(' ', microtime());
     $request["nonce"] = $nonce[1] . str_pad(substr($nonce[0], 2, 6), 6, '0');
     }
     // set
     $postdata = http_build_query($request, '', '&');
     $sign = hash_hmac('sha512', $path . hash('sha256', $request["nonce"] . $postdata, true), base64_decode($secret), true);
     $headers = array(
     'API-Key: ' . $key,
     'API-Sign: ' . base64_encode($sign)
     );


HELP! Thank you in advance

Replies

A good place to start here is the CryptoCompatibility sample code. It includes Objective-C for both SHA-256 and HMAC.

When it comes to debugging, I strongly recommend that you instrument your working code (say your PHP) to hex dump between each step of the algorithm. You can then instrument your Objective-C code to do the same, and compare the outputs. This will let you track down where the two diverge.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@apple.com"