Base64 issue in NSMutableURLRequest POST message?

余生颓废 提交于 2019-12-22 20:01:10

问题


I'm having communcation issues between my app and the server. I'm using RNCryptor to encrypt a message, which I then base64 encode and transfer to the server in the request. This is done in both the DATA header, and within the http body as post data. I think I'm making a mistake in how I'm converting & transferring the base64 encoded message via POST.

If I receive the encrypted message via the header, it decrypts perfectly fine, every single time. However, if I take the message via the POST data, I'm getting varying results. Most of the time, it fails, else it partially decrypts (first few letters), with 1 in 20 or so successful decryptions.

The objective-c code is:

- (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 code:

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);

Many thanks in advance!


回答1:


I know this is a old question, but for a long time I used the same solution and the problem was that we are not encoding properly the url before making the request to the server. The documentation says:

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

And here is how to encode the string:/

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

And to get the string again:

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

I think this is the best we can do, because we make sure that string will be properly encoded and during the request the symbols will not be replaced for other thing. here is the references:

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:


I've just found the solution. During the request, the '+' symbols are being interpreted as whitespaces by the server, breaking the base64 code. The following line fixed this problem:

postMessage       = [postMessage stringByReplacingOccurrencesOfString:@"+" withString:@"%2B"];



回答3:


you can check your encoded/decoded string, in this url

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

As you can see "+" change by "%2B" when you press encode button.



来源:https://stackoverflow.com/questions/14835546/base64-issue-in-nsmutableurlrequest-post-message

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!