无效的SMS API iOS iOS错误代码的签名Sinch:40102消息:无效签名



我正在使用SINCH来供SMS发送MSG到用户,但是没有针对iOS API的详细文档,我正在使用它来生成哈希和消息摘要身份验证代码,但是我得到了

" errorcode":40102,"消息":"无效签名。","参考":

 NSString* phoneNumber = @" ";
    NSString* appKey = @" ";
    NSString* appSecret = @" ";
    NSString* message = @" Hello! Your table has been cancelled. Thank you.";
    NSString* httpVerb = @"POST";
    NSString* contentType = @"application/json";
    NSString* path = @"/v1/sms/+91";

    NSString* userCredentials = [NSString stringWithFormat:@"application\%@:%@",appKey,appSecret];
    NSString* body = [NSString stringWithFormat:@"{"message":"%@"}",message];
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    NSTimeZone *timeZone = [NSTimeZone timeZoneWithName:@"UTC"];
    [dateFormatter setTimeZone:timeZone];
    [dateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss'Z'"];
    NSString *dateString = [dateFormatter stringFromDate:[NSDate date]];
    NSString* canonicalizedHeaders = [NSString stringWithFormat:@"x-timestamp:%@",dateString];

    NSString* url = [NSString stringWithFormat:@"https://messagingapi.sinch.com/v1/sms/%@",phoneNumber];
    NSString* contentMd5 = [self encodeBase64String:[self md5:body]];
    NSString* stringToSign =[NSString stringWithFormat:@"%@n%@n%@n%@n%@",httpVerb,contentMd5,contentType,canonicalizedHeaders,path];
    NSString* signature =  [self signature:appSecret withMessage:stringToSign];

    NSString* authorization = [NSString stringWithFormat:@"Application %@:%@",appKey,signature];


- (NSString*)encodeBase64String:(NSString *)stringToEncode {
    NSData *dataToEncode = [stringToEncode dataUsingEncoding:NSUTF8StringEncoding];
    NSData *encodedData = [dataToEncode base64EncodedDataWithOptions:0];
    NSString *encodedString = [[NSString alloc] initWithData:encodedData encoding:NSUTF8StringEncoding];
    return encodedString; }
- (NSString *) md5:(NSString *) input {
    const char *cstr = [input UTF8String];
    unsigned char result[16];
    CC_MD5(cstr, strlen(cstr), result);
    return [NSString stringWithFormat:
            @"%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",
            result[0], result[1], result[2], result[3],
            result[4], result[5], result[6], result[7],
            result[8], result[9], result[10], result[11],
            result[12], result[13], result[14], result[15]
            ]; }

-(NSString*)signature:(NSString*)secret withMessage:(NSString*)message {

    NSString* key = secret;
    NSString* data = message;
    const char *cKey = [key cStringUsingEncoding:NSASCIIStringEncoding];
    const char *cData = [data cStringUsingEncoding:NSASCIIStringEncoding];
    unsigned char cHMAC[CC_SHA256_DIGEST_LENGTH];
    CCHmac(kCCHmacAlgSHA256, cKey, strlen(cKey), cData, strlen(cData), cHMAC);
    NSData *hash = [[NSData alloc] initWithBytes:cHMAC length:sizeof(cHMAC)];
    NSLog(@"%@", hash);
    NSString* signature = [self base64forData:hash];
    NSLog(@"%@", signature);
    return signature; }
- (NSString*)base64forData:(NSData*)theData {
    const uint8_t* input = (const uint8_t*)[theData bytes];
    NSInteger length = [theData length];
    static char table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789=";
    NSMutableData* data = [NSMutableData dataWithLength:((length + 2) / 3) * 4];
    uint8_t* output = (uint8_t*)data.mutableBytes;
    NSInteger i;
    for (i=0; i < length; i += 3) {
        NSInteger value = 0;
        NSInteger j;
        for (j = i; j < (i + 3); j++) {
            value <<= 8;
            if (j < length) {  value |= (0xFF & input[j]);  }  }  NSInteger theIndex = (i / 3) * 4;  output[theIndex + 0] = table[(value
>> 18) & 0x3F];
        output[theIndex + 1] = table[(value >> 12) & 0x3F];
        output[theIndex + 2] = (i + 1) < length ? table[(value >> 6) & 0x3F] : '=';
        output[theIndex + 3] = (i + 2) < length ? table[(value >> 0) & 0x3F] : '=';
    }
    return [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding]; }

需要在JSON或BASE64中格式化身体。这部分代码对我有用:

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:hostname]
                                                       cachePolicy:NSURLRequestReloadIgnoringLocalAndRemoteCacheData
                                                   timeoutInterval:TIMEOUT];
[request setHTTPMethod:@"POST"];
[request addValue:@"application/json; charset=UTF-8" forHTTPHeaderField:@"content-type"];
[request addValue:dateString forHTTPHeaderField:@"x-timestamp"];
NSString *authStr = [NSString stringWithFormat:@"application\%@:%@",appKey,appSecret];
NSData *authData = [authStr dataUsingEncoding:NSUTF8StringEncoding];
NSString *authValue = [NSString stringWithFormat: @"Basic %@",[authData base64EncodedStringWithOptions:0]];
[request addValue:authValue forHTTPHeaderField:@"authorization"];
NSDictionary *messageSetup =    @{
                                    @"message" : @"This is where your message goes",
                                    @"from": @"YOUR NUMBER i.e. 555-555-5555"
                                };
NSData *dataFormatted = [NSJSONSerialization dataWithJSONObject:messageSetup options:0 error:nil];
[request setHTTPBody:dataFormatted];
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request
                                            completionHandler:^(NSData *data, NSURLResponse *response, NSError *error)
                                  {
                                      NSString *myString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
                                      NSLog(@"String Return: %@",myString);
                                  }];
[dataTask resume];

最新更新