2016-09-15 10 views
1

에서 나는 다음과 같은 데이터를 Arcane 라이브러리를 사용하여 아이폰 OS에서 SHA256을 생성하려고 :생성 SHA256는 아이폰 OS

문자열 : Amount=50&BillerID=59&ChannelID=2&Context=34|check|test&ReturnURL=https://uat.myfatoora.com/ReceiptPOC.aspx&TxnRefNum=000000000020003&UserName=DCS

키 : 71DD0F73AFFBB47825FF9864DDE95F3B 결과가 I가

409dc622b3bef5c9fc46e45c3210111fcb4536d3a55833316fe0dc8154b3ea34 생각되었다

맞다.

Windows Phone Source Code: 

public static string HmacSha256(string secretKey, string value) 
    { 
     var msg = CryptographicBuffer.ConvertStringToBinary(value, BinaryStringEncoding.Utf8); 
     byte[] convertedHash = new byte[secretKey.Length/2]; 

     for (int i = 0; i < secretKey.Length/2; i++) 
     { 
      convertedHash[i] = (byte)Int32.Parse(secretKey.Substring(i * 2, 2), System.Globalization.NumberStyles.HexNumber); 
     } 

     // Create HMAC. 
     var objMacProv = MacAlgorithmProvider.OpenAlgorithm(MacAlgorithmNames.HmacSha256); 
     CryptographicHash hash = objMacProv.CreateHash(convertedHash.AsBuffer()); 

     hash.Append(msg); 
     return CryptographicBuffer.EncodeToHexString(hash.GetValueAndReset()); 

    } 

을하고 그 결과는 다음과 같습니다 : 그러나 Windows 대응은 다음과 같은 코드를 사용하여 SHA256을 생성 내가 가진 것과 다른 94a20ca39c8487c7763823ec9c918d9e38ae83cb741439f6d129bcdef9edba73. 누군가가 이것으로 나를 도울 수 있고 위의 코드가 무엇을하는지 알려주고 iOS에서 어떻게 복제 할 수 있습니까?

편집 :

iOS Source code 

let key = self.md5(string: "71DD0F73AFFBB47825FF9864DDE95F3B") 

    let hash = HMAC.SHA256(str, key: key) 
+1

당신은 아이폰 OS 측면에 대한 코드를 보이지 않았다. 또한 SHA256과 HMAC-SHA256은 다른 것들입니다. –

+0

@SamKuhmonen : iOS 소스를 추가했습니다. 그것은 Arcane 라이브러리를 사용하고 있습니다. –

답변

2

여기서 핵심은 16 진수 문자열 인 비밀 키를 NSData로 변환해야한다는 것입니다. 즉, NSData 바이트 스트림은 비밀과 같이 "보입니다".

이것은 당신이 원하는 일을해야합니다

// Hex string to NSData conversion from here http://stackoverflow.com/questions/7317860/converting-hex-nsstring-to-nsdata 
    NSString *secret = @"71DD0F73AFFBB47825FF9864DDE95F3B"; 
    NSData *dataIn = [@"Amount=50&BillerID=59&ChannelID=2&Context=34|check|test&ReturnURL=https://uat.myfatoora.com/ReceiptPOC.aspx&TxnRefNum=000000000020003&UserName=DCS" dataUsingEncoding:NSUTF8StringEncoding]; 
    NSMutableData *macOut = [NSMutableData dataWithLength:CC_SHA256_DIGEST_LENGTH]; 

    secret = [secret stringByReplacingOccurrencesOfString:@" " withString:@""]; 
    NSMutableData *secretData = [[NSMutableData alloc] init]; 
    unsigned char whole_byte; 
    char byte_chars[3] = {'\0','\0','\0'}; 
    int i; 
    for (i=0; i < [secret length]/2; i++) { 
     byte_chars[0] = [secret characterAtIndex:i*2]; 
     byte_chars[1] = [secret characterAtIndex:i*2+1]; 
     whole_byte = strtol(byte_chars, NULL, 16); 
     [secretData appendBytes:&whole_byte length:1]; 
    } 

    CCHmac(kCCHmacAlgSHA256, secretData.bytes, secretData.length, dataIn.bytes, dataIn.length, macOut.mutableBytes); 

    NSMutableString *stringOut = [NSMutableString stringWithCapacity:macOut.length]; 
    const unsigned char *macOutBytes = macOut.bytes; 

    for (NSInteger i=0; i<macOut.length; ++i) { 
     [stringOut appendFormat:@"%02x", macOutBytes[i]]; 
    } 

    NSLog(@"dataIn: %@", dataIn); 
    NSLog(@"macOut: %@", macOut); 
    NSLog(@"stringOut: %@", stringOut); 

출력 :

2016년 9월 27일 20 : 18 : 54.181 JKS [27562 : 5321334] DATAIN : < 416d6f75 6e743d35 30264269 6c6c6572 49443d35 39264368 616e6e65 6c49443d 3226436f 6e746578 743d3334 7c636865 636b7c74 65,737,426 52,657,475 726e5552 4c3d6874 7470733a 2f2f7561 742e6d79 6661746f 6f72612e 636f6d2f 52,656,365 69,707,450 73,707,826 4f432e61 54786e52 65664e75 6d3d3030 30,303,030 30,303,030 32,303,030 33,265,573 65724e61 6d653d44 4353>

2016년 9월 27일 20 : 18 : 54.181 JKS [27,562 : 5,321,334] macOut : < 94a20ca3 9c8487c7 763823ec 9c918d9e 38ae83cb 741439f6 d129bcde f9edba73>

2016년 9월 27일 20시 18분 54초.181 JKS [27562 : 5321334] stringOut : 94a20ca39c8487c7763823ec9c918d9e38ae83cb741439f6d129bcdef9edba73

(코드 정리해야한다) 당신은 Data

에 16 진수 문자열로 변환이 확장을 사용할 수 있습니다

// http://stackoverflow.com/questions/29799361/generate-a-hmac-swift-sdk8-3-using-cchmac 
func generateHMAC(key: String, data: String) -> String { 
    let keyData = key.dataFromHexadecimalString()! as NSData 
    let dataIn = data.data(using: .utf8)! as NSData 
    var result: [CUnsignedChar] 
    result = Array(repeating: 0, count: Int(CC_SHA256_DIGEST_LENGTH)) 
    CCHmac(CCHmacAlgorithm(kCCHmacAlgSHA256), keyData.bytes, keyData.length, dataIn.bytes, dataIn.length, &result) 

    let hash = NSMutableString() 
    for val in result { 
     hash.appendFormat("%02hhx", val) 
    } 

    return hash as String 
} 

스위프트와 업데이트

// Modified slightly http://stackoverflow.com/questions/26501276/converting-hex-string-to-nsdata-in-swift 
extension String { 

    func dataFromHexadecimalString() -> Data? { 
     var data = Data(capacity: characters.count/2) 

     let regex = try! NSRegularExpression(pattern: "[0-9a-f]{1,2}", options: .caseInsensitive) 
     regex.enumerateMatches(in: self, options: [], range: NSMakeRange(0, characters.count)) { match, flags, stop in 
      let byteString = (self as NSString).substring(with: match!.range) 
      var num = UInt8(byteString, radix: 16) 
      data.append(&num!, count: 1) 
     } 

     return data 
    } 
} 

다음을 사용하십시오.

let secret = "71DD0F73AFFBB47825FF9864DDE95F3B" 
    let value = "Amount=50&BillerID=59&ChannelID=2&Context=34|check|test&ReturnURL=https://uat.myfatoora.com/ReceiptPOC.aspx&TxnRefNum=000000000020003&UserName=DCS" 

    print("\(generateHMAC(key: secret, data: value))") 

귀하의 출력은 당신은 당신의 브리지 헤더에 #import <CommonCrypto/CommonCrypto.h>가 필요합니다 94a20ca39c8487c7763823ec9c918d9e38ae83cb741439f6d129bcdef9edba73

해야한다.

+0

오, #import

+0

아, Obj-C이지만 유감스럽게도 Swift와 똑같이 할 수 있어야합니다. 'CCHmac'를 사용할 수 있습니다. 여기에 대한 링크가 있습니다 http://stackoverflow.com/questions/29799361/generate-a-hmac-swift-sdk8-3-using-cchmac –

+0

안녕, 대답 주셔서 감사합니다. Data.data가'let dataIn = data.data (.utf8을 사용하십시오)에 무엇이 있는지 알려주십시오. as NSData'라고 입력하면 오류가 발생합니다. String을 NSData로 변환한다고 가정합니다. –

1

윈도우 코드는 16 진수로 해석, 문자열을 받아, 한 바이트로 두 문자 시간을 변환합니다.

대부분의 Mac 코드는 인 문자열을 사용합니다. 키가 "71"로 시작하기 때문에 Windows 코드는 값이 0x71 = 129 인 단일 바이트로 간주하며 Mac 코드는 '7'= 55 및 '1'= 49 값을 갖는 2 바이트로 취급합니다.

Windows에서하는 것처럼 정확히 Mac에서 바이트를 변환하기 만하면됩니다. 생각할 수없는 일을해야하고 실제로 해시 계산을하는 방법을 보려면 Mac 라이브러리의 소스 코드를 살펴 봐야 할 것입니다.

+0

가 I 0 ... secretKey.length/2 { 하자 범위 내가이 '같은 것을하려고 NSMakeRange = (I는 2 * 2) 경우 range.location <32 { convertedHash.appendData (비밀 키 .substringWithRange (range) .dataUsingEncoding (NSUTF8StringEncoding)!) } } 하지만 도움이되지 않았습니다. 약간의 코드를 올리시겠습니까? –

0

#import <CommonCrypto/CommonHMAC.h> 
 

 
+ (NSString *)hmacSHA256EncryptString{ 
 

 

 
    NSString * parameterSecret = @"input secret key"; 
 
    NSString *plainString = @"input encrypt content string"; 
 
    const char *secretKey = [parameterSecret cStringUsingEncoding:NSUTF8StringEncoding]; 
 
    const char *plainData = [plainString cStringUsingEncoding:NSUTF8StringEncoding]; 
 
    unsigned char cHMAC[CC_SHA256_DIGEST_LENGTH]; 
 
    CCHmac(kCCHmacAlgSHA256, secretKey, strlen(secretKey), plainData, strlen(plainData), cHMAC); 
 
    NSData *HMACData = [NSData dataWithBytes:cHMAC length:sizeof(cHMAC)]; 
 
    const unsigned char *bufferChar = (const unsigned char *)[HMACData bytes]; 
 
    NSMutableString *hmacString = [NSMutableString stringWithCapacity:HMACData.length * 2]; 
 
    for (int i = 0; i < HMACData.length; ++i){ 
 
     [hmacString appendFormat:@"%02x", bufferChar[i]]; 
 
    } 
 
    return hmacString; 
 
    
 
}