2013-02-12 5 views
2

내 앱과 서버 사이에 통신 문제가 있습니다. RNCryptor를 사용하여 메시지를 암호화 한 다음 요청을 통해 base64로 인코딩하여 서버로 전송합니다. 이 작업은 DATA 헤더와 http 본문에서 모두 게시물 데이터로 수행됩니다. 내가 어떻게 & POST를 통해 base64로 인코딩 된 메시지를 변환 오전 실수하고있어 생각합니다.NSMutableURLRequest POST 메시지의 Base64 문제가 발생 했습니까?

헤더를 통해 암호화 된 메시지를 받으면 매번 완벽하게 해독합니다. 그러나 POST 데이터를 통해 메시지를 가져 오는 경우 다양한 결과가 나타납니다. 대부분의 경우, 실패합니다. 그렇지 않으면 부분적으로 암호를 해독합니다 (처음 몇 글자).

목적-C 코드는 다음과 같습니다

- (NSString *)sendEncryptedTestMessage:(NSString *)address{ 
    NSString* messageContent = @"Hello my name is Bob."; 
    NSError * error    = nil; 
    NSString* responseString2 = nil; 

    NSData* postData = [RNEncryptor encryptData:[messageContent dataUsingEncoding:NSUTF8StringEncoding] 
            withSettings:kRNCryptorAES256Settings 
             password:@"123456" 
              error:&error]; 

    NSString* messageServer  = [NSString base64forData:postData]; 
    NSString* postMessage  = [@"message=" stringByAppendingString:messageServer]; 
       postData   = [postMessage dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES]; // problem here I think 

    NSString* postLength  = [NSString stringWithFormat:@"%ld",(unsigned long)[postData length]]; 

    NSURL* URLToRequest  = [NSURL URLWithString:address]; 

    NSMutableURLRequest* semisystem = [[[NSMutableURLRequest alloc] initWithURL:URLToRequest] autorelease]; 

    [semisystem setHTTPMethod:@"POST"]; 

    [semisystem setHTTPBody:postData]; 
    [semisystem setValue:postLength       forHTTPHeaderField:@"Content-Length"]; 
    [semisystem setValue:self.activationURL     forHTTPHeaderField:@"EncryptionKey"]; 
    [semisystem setValue:messageServer      forHTTPHeaderField:@"data"]; 

    NSURLResponse* response; 
    NSData* data = [NSURLConnection sendSynchronousRequest:semisystem 
             returningResponse:&response 
                error:&error]; 

    responseString2 = [NSString stringWithFormat:@"%.*s", (int)[data length], [data bytes]]; 
    return responseString2; 
} 

PHP 코드 : 사전에

function decrypt2($b64_data,$password) 
    { 
      // back to binary 
      //$bin_data = mb_convert_encoding($b64_data, "UTF-8", "BASE64"); 
      $bin_data = base64_decode($b64_data); 
      // extract salt 
      $salt = substr($bin_data, 2, 8); 
      // extract HMAC salt 
      $hmac_salt = substr($bin_data, 10, 8); 
      // extract IV 
      $iv = substr($bin_data, 18, 16); 
      // extract data 
      $data = substr($bin_data, 34, strlen($bin_data) - 34 - 32); 
      $dataWithoutHMAC = chr(2).chr(1).$salt.$hmac_salt.$iv.$data; 
      // extract HMAC 
      $hmac = substr($bin_data, strlen($bin_data) - 32); 
      // make HMAC key 
      $hmac_key = pbkdf2('SHA1', $password, $hmac_salt, 10000, 32, true); 
      // make HMAC hash 
      $hmac_hash = hash_hmac('sha256', $dataWithoutHMAC , $hmac_key, true); 
      // check if HMAC hash matches HMAC 
      if($hmac_hash != $hmac) { 
       echo "HMAC mismatch".$nl.$nl.$nl; 
       // return false; 
      } 
      // make data key 
      $key = pbkdf2('SHA1', $password, $salt, 10000, 32, true); 
      // decrypt 
      $ret = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, $data, MCRYPT_MODE_CBC, $iv);  
     return $ret; 
    } 
$passkey = "123456"; 

$messageBase64     = $_POST['message'];// THIS barely works 
$messageBase64    = $_SERVER['HTTP_DATA'];// THIS WORKS 
$message    = decrypt2($messageBase64,$passkey); 

많은 감사합니다!

답변

3

을하지만, 오랜 시간 동안 나는 동일한 솔루션을 사용하고 우리가 요청을하기 전에 제대로 URL을 인코딩되지 않는다는 문제가 있었다 섬기는 사람.

NSString* stringEncoded = CFBridgingRelease 
    (CFURLCreateWithString(kCFAllocatorDefault, encodedString, NULL)); 

나는 이것이 최고라고 생각 :

According to RFC 3986, the reserved characters in a URL are: 
    reserved = gen-delims/sub-delims 
    gen-delims = ":"/"/"/"?"/"#"/"["/"]"/"@" 
    sub-delims = "!"/"$"/"&"/"'"/"("/")" 
      /"*"/"+"/","/";"/"=" 

을 그리고 여기에 문자열 인코딩하는 방법은 다음과 같습니다 : 문서는 말한다/

CFStringRef encodedString = 
    CFURLCreateStringByAddingPercentEscapes(
    kCFAllocatorDefault, 
    (__bridge CFStringRef)(originalString), 
    NULL, 
    CFSTR(":/?#[]@!$&'()*+,;="),kCFStringEncodingUTF8); 

를 다시 문자열을 얻을 수 우리는 문자열이 올바르게 인코딩되었는지 확인하고 요청 중에 심볼이 다른 것으로 대체되지 않기 때문에 할 수 있습니다. 당신이로 "+"변화를 볼 수있는

http://developer.apple.com/library/ios/#documentation/CoreFoundation/Reference/CFURLRef/Reference/reference.html#//apple_ref/c/func/CFURLCreateStringByAddingPercentEscapes

http://developer.apple.com/library/ios/#documentation/NetworkingInternetWeb/Conceptual/NetworkingOverview/WorkingWithHTTPAndHTTPSRequests/WorkingWithHTTPAndHTTPSRequests.html

2

방금 ​​해결책을 찾았습니다. 요청 중에 '+'기호는 서버에 의해 공백으로 해석되어 base64 코드를 위반합니다. 다음 줄은이 문제 해결 :이이 오래된 질문 알고

postMessage  = [postMessage stringByReplacingOccurrencesOfString:@"+" withString:@"%2B"]; 
-1
당신이 당신의 인코딩/디코딩 된 문자열을 확인하실 수 있습니다

,이 URL을

http://meyerweb.com/eric/tools/dencoder/

에서 : 여기 은 참조입니다 "% 2B"인코딩 단추를 누르면.