Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在iOS SDK中创建密码摘要_Ios_Objective C_Soap_Ws Security - Fatal编程技术网

在iOS SDK中创建密码摘要

在iOS SDK中创建密码摘要,ios,objective-c,soap,ws-security,Ios,Objective C,Soap,Ws Security,我正在将DigestPassword web服务集成到我的iPhone应用程序中。为此,我需要生成nonce和passwordDigest。我努力了,但在谷歌搜索中找不到任何有效的例子 我已经按照以下方式完成了:更新代码: NSString *user = @"XXXXXXXXXXXXXXXXXXXXXX"; NSNumber *nonce = @(arc4random()); NSLog(@"nonce %@",[self encodeStringTo64:[nonce stringValue

我正在将DigestPassword web服务集成到我的iPhone应用程序中。为此,我需要生成nonce和passwordDigest。我努力了,但在谷歌搜索中找不到任何有效的例子

我已经按照以下方式完成了:更新代码:

NSString *user = @"XXXXXXXXXXXXXXXXXXXXXX";
NSNumber *nonce = @(arc4random());
NSLog(@"nonce %@",[self encodeStringTo64:[nonce stringValue]]);
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"];
NSString *created = [dateFormatter stringFromDate:[NSDate date]];
NSLog(@"created %@",created);
NSString *digest_concat = [NSString stringWithFormat:@"%@%@%@", nonce, created, @"Pwd@123"];

NSData *digestBytes = [self shaa1:digest_concat];
NSString *digestBase64 = [self base64forData:digestBytes];
NSLog(@"digestBase64 %@",digestBase64);

NSString *strSOAP = [NSString stringWithFormat:@"<soap:Envelope xmlns:soap=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:v1=\"http://sita.aero/iborders/external/ReferralManagementServiceWSDLType/V1\"><soap:Header><wsse:Security xmlns:wsse=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd\" xmlns:wsu=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd\"><wsse:UsernameToken wsu:Id=\"UsernameToken-27E173B8CF239BE6F01440582357416191\"><wsse:Username>%@</wsse:Username><wsse:Password Type=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest\">%@</wsse:Password><wsse:Nonce EncodingType=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary\">%@</wsse:Nonce><wsu:Created>%@</wsu:Created></wsse:UsernameToken></wsse:Security></soap:Header><soap:Body><v1:SearchReferralsRequest><v1:ReferralSearchCriteria><ReferralId>2038100</ReferralId></v1:ReferralSearchCriteria><v1:Paging><FetchNumber>1</FetchNumber><ResultsPerFetch>1</ResultsPerFetch></v1:Paging></v1:SearchReferralsRequest></soap:Body></soap:Envelope>",user,digestBase64,[self encodeStringTo64:[nonce stringValue]],created];

- (NSString*)encodeStringTo64:(NSString*)fromString{
    NSData *plainData = [fromString dataUsingEncoding:NSUTF8StringEncoding];
    NSString *base64String;
    if ([plainData respondsToSelector:@selector(base64EncodedStringWithOptions:)]) {
        base64String = [plainData base64EncodedStringWithOptions:kNilOptions];  // iOS 7+
    } else {
        base64String = [plainData base64Encoding];                              // pre iOS7
    }
    return base64String;
}

- (NSData *)shaa1:(NSString *)input {
NSData *data = [input dataUsingEncoding:NSUTF8StringEncoding];
uint8_t digest[CC_SHA1_DIGEST_LENGTH];
CC_SHA1(data.bytes, (CC_LONG) data.length, digest);
return [NSData dataWithBytes:digest length:CC_SHA1_DIGEST_LENGTH];
NSString*user=@“XXXXXXXXXXXXXXXXXXXXXX”;
NSNumber*nonce=@(arc4random());
NSLog(@“nonce%@,[self-encodeStringTo64:[nonce-stringValue]]);
NSDateFormatter*dateFormatter=[[NSDateFormatter alloc]init];
[dateFormatter setDateFormat:@“yyyy-MM-dd'T'HH:MM:ss.SSS'Z'”;
NSString*created=[dateFormatter stringFromDate:[NSDate date]];
NSLog(@“已创建%@”,已创建);
NSString*digest_concat=[NSString stringWithFormat:@“%@%@@”,当前,已创建,@”Pwd@123"];
NSData*digestBytes=[self-shaa1:digest_concat];
NSString*digestBase64=[self-base64forData:digestBytes];
NSLog(@“digestBase64%@”,digestBase64);
NSString*strSOAP=[NSString stringWithFormat:@“%@%@%@%@203810011”,用户,digestBase64,[self-encodeStringTo64:[nonce stringValue]],已创建];
-(NSString*)将字符串编码为64:(NSString*)fromString{
NSData*plainData=[fromString dataUsingEncoding:NSUTF8StringEncoding];
NSString*base64String;
if([plainData respondsToSelector:@selector(base64EncodedStringWithOptions:)])){
base64String=[plainData base64EncodedStringWithOptions:kNilOptions];//iOS 7+
}否则{
base64String=[plainData base64Encoding];//iOS7之前的版本
}
返回base64String;
}
-(NSData*)shaa1:(NSString*)输入{
NSData*data=[输入数据使用编码:NSUTF8StringEncoding];
uint8_t摘要[抄送摘要长度];
CC_SHA1(data.bytes,(CC_LONG)data.length,摘要);
返回[NSData DATAFTHBYTES:摘要长度:CC_SHA1_摘要长度];
}

有人能检查一下我的代码来创建nonce和password digest吗?请告诉我我犯了什么错误,因为我无法使用它访问web服务?我总是收到过期的消息错误。 错误:


soap:发送方
ns1:MessageExpired
消息已过期
编辑:我想要的SOAP请求:

<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:v1="http://xxxxx/xxxx/external/ServiceWSDLType/V1">
 <soap:Header>
    <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
      <wsse:UsernameToken wsu:Id="UsernameToken-XXXXX">
          <wsse:Username>XXXXXXXXXXXXXXXXXXX</wsse:Username>
          <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest">iAdbggkXsbNih5wBJ8M2tyyVWiA=</wsse:Password>
          <wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">b8SD2g2iiVvihx7ajVwPfw==</wsse:Nonce>
          <wsu:Created>2015-08-28T07:16:04.857Z</wsu:Created>
       </wsse:UsernameToken>
    </wsse:Security>
 </soap:Header>
 <soap:Body>
    <v1:SearchReferralsRequest>
       <v1:ReferralSearchCriteria>
          <ReferralId>213213</ReferralId>
       </v1:ReferralSearchCriteria>
       <v1:Paging>
          <FetchNumber>1</FetchNumber>
          <ResultsPerFetch>1</ResultsPerFetch>
       </v1:Paging>
    </v1:SearchReferralsRequest>
 </soap:Body>
</soap:Envelope>

XXXXXXXXXXXXXXXXX
IADBGGXSBNIH5WBJ8M2tyVWIA=
B8SD2G2IVVIHX7AJVWPFW==
2015-08-28 07:16:04.857Z
213213
1.
1.

我认为您需要发送SHA1摘要,而无需额外编码为十六进制字符串

请为SHA1尝试此功能:

- (NSData *)sha1:(NSString *)input {
    NSData *data = [input dataUsingEncoding:NSUTF8StringEncoding];
    uint8_t digest[CC_SHA1_DIGEST_LENGTH];
    CC_SHA1(data.bytes, (CC_LONG) data.length, digest);
    return [NSData dataWithBytes:digest length:CC_SHA1_DIGEST_LENGTH];
}
还要检查密码摘要中的时间值是否与
wsu:Created
相同

更新#1

此外,您在密码摘要中使用base64 nonce,但在文档中,公式为:

Password_Digest=Base64(SHA-1(nonce+created+Password))

所以nonce必须是数字,而不是base64编码的数字。请尝试以下密码摘要代码:

NSNumber *nonce = @(arc4random());

NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"];
NSString *created = [dateFormatter stringFromDate:[NSDate date]];

NSString *digest_concat = [NSString stringWithFormat:@"%@%@%@", nonce, created, password];
更新#2

由于时区的原因,您的邮件似乎已过期。来自规范Web服务安全:SOAP消息安全版本1.1.1

本规范定义并说明了以下方面的时间参考: XML架构中定义的xsd:dateTime类型。建议 所有时间引用都使用此类型。所有引用必须使用UTC 时间实现不能生成指定 闰秒。但是,如果使用了其他时间类型,则 必须指定ValueType属性(如下所述)以指示 时间格式的数据类型。请求者和接收者不应 依赖于其他支持时间分辨率比 毫秒

使用UTC时区:

NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"];
[dateFormatter setTimeZone:[NSTimeZone timeZoneWithAbbreviation:@"UTC"]];
NSString *created = [dateFormatter stringFromDate:[NSDate date]];

您可以查看服务器日志以了解有关错误的更多信息吗?可以,它在SOAPUI中工作,但我无法在目标c代码中复制相同的内容。我认为您需要在问题中显示完整的SOAP请求。我添加了所需的SOAP请求,但不知何故,我无法在此处格式化它。我尝试了此方法,但我没有得到与SOAPUI类似的结果。通过您的实现,您将得到与SOAPUI相同的结果SOAPUI?为了测试我的程序,我从SOAPUI生成nonce、date和password,但我不提交它(如果我提交请求,它会工作)。然后,我在程序中使用相同的nonce和createdate来获得响应。它与soapui生成的摘要密码不匹配。我已根据您的建议更新了我的请求。现在生成的请求看起来与SOAPUI生成的请求相似,但它仍然不工作,并且我收到了相同的消息Expired error。请查看上面更新的代码。嗨,John,非常感谢,我已经在这个问题上纠缠了大约一周,您使用UTC时区的建议为我解决了这个问题。我很惊讶我在互联网上的任何地方都找不到这个。在这件事上你是我的救星。。。我希望我能给你一杯啤酒:)
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"];
[dateFormatter setTimeZone:[NSTimeZone timeZoneWithAbbreviation:@"UTC"]];
NSString *created = [dateFormatter stringFromDate:[NSDate date]];