Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/96.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
SHA1 c#windows应用商店应用程序和Objective-c iOS之间的哈希差异_C#_Ios_Objective C_Windows Store Apps_Sha1 - Fatal编程技术网

SHA1 c#windows应用商店应用程序和Objective-c iOS之间的哈希差异

SHA1 c#windows应用商店应用程序和Objective-c iOS之间的哈希差异,c#,ios,objective-c,windows-store-apps,sha1,C#,Ios,Objective C,Windows Store Apps,Sha1,Surface pro上的我的Windows应用商店应用程序使用SHA1向服务器发送哈希密码。我想为iOS应用程序做同样的事情,但我得到了不同的结果,我只是不知道为什么 在将NSString转换为cString时,我尝试了不同的编码(NSASCII UTF8 UniCode),但没有成功 c#Windows应用商店应用程序-Surface pro /// <summary> /// Literal copy of the values from web config mach

Surface pro上的我的Windows应用商店应用程序使用SHA1向服务器发送哈希密码。我想为iOS应用程序做同样的事情,但我得到了不同的结果,我只是不知道为什么

在将NSString转换为cString时,我尝试了不同的编码(NSASCII UTF8 UniCode),但没有成功

c#Windows应用商店应用程序-Surface pro

/// <summary>
    /// Literal copy of the values from web config machinekey
    /// </summary>
    const String validationKey = "6DB51F17C529AD3CABEC50B3C89CB21F4F1422F58A5B42D0E8DB8CB5CDA146511891C1BAF47F8D29401E3400267682B202B7DA146511891C1BAF47F8D29401E3";

    public static string HmacSha1(string baseString)
    {
        var crypt = MacAlgorithmProvider.OpenAlgorithm("HMAC_SHA1");
        var buffer = CryptographicBuffer.CreateFromByteArray(Encoding.Unicode.GetBytes(baseString));
        var keyBuffer = Windows.Security.Cryptography.CryptographicBuffer.CreateFromByteArray(HexToByte(validationKey));
        var key = crypt.CreateKey(keyBuffer);
        var sigBuffer = CryptographicEngine.Sign(key, buffer);
        string signature = CryptographicBuffer.EncodeToBase64String(sigBuffer);
        return signature;
    }

    //
    // HexToByte
    //   Converts a hexadecimal string to a byte array. Used to convert encryption
    // key values from the configuration.
    //
    private static byte[] HexToByte(string hexString)
    {
        byte[] returnBytes = new byte[hexString.Length / 2];
        for (int i = 0; i < returnBytes.Length; i++)
            returnBytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16);
        return returnBytes;
    }

所以一些天才帮我弄明白了。在c#代码中,密码使用Unicode编码,如下所示:

Encoding.Unicode.GetBytes(baseString)
这意味着我应该将Objective-C中的NSASCI编码行更改为:

const char *cPassword = [password cStringUsingEncoding:NSUnicodeStringEncoding];
现在来了一件棘手的事情。Unicode对类似“Welkom123”的字符串进行如下编码:
W/0e/0l/0k/0o/0m/01/02/03/0
。这意味着我不能使用
strlen(cData)
来确定cData的长度,因为当遇到
/0
时,cData将停止计数,所以长度一直是错误的。我不得不用
(password.length*2)
替换
strlen(cData)

但即便如此,结果仍然不正确。密钥必须变成十六进制数据,就像c代码一样。然后,应使用NSData创建CCHmac。此代码将NSString转换为具有十六进制值的NSData:

int len = (int)([inputString length] / 2);    // Target length
unsigned char *buf = malloc(len);
unsigned char *whole_byte = buf;
char byte_chars[3] = {'\0','\0','\0'};

int i;
for (i=0; i < [inputString length] / 2; i++) {
    byte_chars[0] = [inputString characterAtIndex:i*2];
    byte_chars[1] = [inputString characterAtIndex:i*2+1];
    *whole_byte = strtol(byte_chars, NULL, 16);
    whole_byte++;
}

NSData *data = [NSData dataWithBytes:buf length:len];
free( buf );
return data;
int len=(int)([inputString长度]/2);//目标长度
无符号字符*buf=malloc(len);
无符号字符*整字节=buf;
字符字节_chars[3]={'\0','\0','\0'};
int i;
对于(i=0;i<[inputString长度]/2;i++){
字节_字符[0]=[inputString字符索引:i*2];
字节_字符[1]=[inputString字符索引:i*2+1];
*整字节=strtol(字节字符,空,16);
整字节++;
}
NSData*data=[NSData dataWithBytes:buf length:len];
免费(buf);
返回数据;
最终,总代码如下所示:

-(NSDictionary *)authenticateWithUsername:(NSString *)userName andPassword:(NSString *)password andSyncUrl:(NSString *)syncUrl
{
NSString *key = @"6DB51F17C529AD3CABEC50B3C89CB21F4F1422F58A5B42D0E8DB8CB5CDA146511891C1BAF47F8D29401E3400267682B202B7DA146511891C1BAF47F8D29401E3";
NSData *data = [self stringToHexData:key];
const char *cPassword = [password cStringUsingEncoding:NSUnicodeStringEncoding];
unsigned char cHMAC[CC_SHA1_DIGEST_LENGTH];
CCHmac(kCCHmacAlgSHA1, data.bytes, data.length, cPassword, (password.length * 2), cHMAC);
NSData *HMAC = [[NSData alloc] initWithBytes:cHMAC length:sizeof(cHMAC)];
NSString *hashedPassword = [HMAC base64EncodedStringWithOptions:0];

NSString *clientPassword = hashedPassword;

// some code here left out for readability sake

return dict;
}

- (NSData *) stringToHexData:(NSString *)inputString
{
int len = (int)([inputString length] / 2);    // Target length
unsigned char *buf = malloc(len);
unsigned char *whole_byte = buf;
char byte_chars[3] = {'\0','\0','\0'};

int i;
for (i=0; i < [inputString length] / 2; i++) {
    byte_chars[0] = [inputString characterAtIndex:i*2];
    byte_chars[1] = [inputString characterAtIndex:i*2+1];
    *whole_byte = strtol(byte_chars, NULL, 16);
    whole_byte++;
}

NSData *data = [NSData dataWithBytes:buf length:len];
free( buf );
return data;
}
-(NSDictionary*)验证用户名:(NSString*)用户名和密码:(NSString*)密码和同步URL:(NSString*)同步URL
{
NSString*键=@“6DB51F17C529AD3CABEC50B3C89CB21F4F1422F58A5B420E8DB8CB5CD14651891CAF47F8D29401E3400267682B202B7DA146511891CAF47F8D29401E3”;
NSData*data=[self-stringToHexData:key];
const char*cPassword=[password cStringUsingEncoding:nsunicoding];
无符号字符cHMAC[CC_SHA1_DIGEST_LENGTH];
CCHmac(kCCHmacAlgSHA1,data.bytes,data.length,cPassword,(password.length*2),cHMAC);
NSData*HMAC=[[NSData alloc]initWithBytes:cHMAC长度:sizeof(cHMAC)];
NSString*hashedPassword=[HMAC base64EncodedStringWithOptions:0];
NSString*clientPassword=hashedPassword;
//为了便于阅读,这里省略了一些代码
返回命令;
}
-(NSData*)stringToHexData:(NSString*)inputString
{
int len=(int)([inputString长度]/2);//目标长度
无符号字符*buf=malloc(len);
无符号字符*整字节=buf;
字符字节_chars[3]={'\0','\0','\0'};
int i;
对于(i=0;i<[inputString长度]/2;i++){
字节_字符[0]=[inputString字符索引:i*2];
字节_字符[1]=[inputString字符索引:i*2+1];
*整字节=strtol(字节字符,空,16);
整字节++;
}
NSData*data=[NSData dataWithBytes:buf length:len];
免费(buf);
返回数据;
}

根据您的代码,C#使用Unicode,而Obj-C使用ASCII。。。产生不同的结果是正常的。谢谢你的帮助。如上所述,我尝试了不同的编码。这个cStringUsingEncoding:nsunicoding仍然会得到不同的结果。这可能与c#中的HexToByte有关吗?#可能是@Raptor的副本我看到了你标记为副本的这篇文章。请看一下c#代码的区别(关于Windows应用商店应用程序)。这就是我必须处理的,并且必须使Objective-c代码产生相同的结果。我无论如何都要感谢你调查这个问题。提供C#结果。由于所有输入字符都是ASCII码,因此如果使用
NSASCIIStringEncoding
NSUTF8StringEncoding
则没有区别,但使用
NSUTF8StringEncoding
则没有区别,除非特别需要另一种编码。
-(NSDictionary *)authenticateWithUsername:(NSString *)userName andPassword:(NSString *)password andSyncUrl:(NSString *)syncUrl
{
NSString *key = @"6DB51F17C529AD3CABEC50B3C89CB21F4F1422F58A5B42D0E8DB8CB5CDA146511891C1BAF47F8D29401E3400267682B202B7DA146511891C1BAF47F8D29401E3";
NSData *data = [self stringToHexData:key];
const char *cPassword = [password cStringUsingEncoding:NSUnicodeStringEncoding];
unsigned char cHMAC[CC_SHA1_DIGEST_LENGTH];
CCHmac(kCCHmacAlgSHA1, data.bytes, data.length, cPassword, (password.length * 2), cHMAC);
NSData *HMAC = [[NSData alloc] initWithBytes:cHMAC length:sizeof(cHMAC)];
NSString *hashedPassword = [HMAC base64EncodedStringWithOptions:0];

NSString *clientPassword = hashedPassword;

// some code here left out for readability sake

return dict;
}

- (NSData *) stringToHexData:(NSString *)inputString
{
int len = (int)([inputString length] / 2);    // Target length
unsigned char *buf = malloc(len);
unsigned char *whole_byte = buf;
char byte_chars[3] = {'\0','\0','\0'};

int i;
for (i=0; i < [inputString length] / 2; i++) {
    byte_chars[0] = [inputString characterAtIndex:i*2];
    byte_chars[1] = [inputString characterAtIndex:i*2+1];
    *whole_byte = strtol(byte_chars, NULL, 16);
    whole_byte++;
}

NSData *data = [NSData dataWithBytes:buf length:len];
free( buf );
return data;
}