9

So I have this c# application that needs to ping my web server thats running linux/php stack.
I am having problems with the c# way of base 64 encoding bytes.

my c# code is like:

byte[] encbuff = System.Text.Encoding.UTF8.GetBytes("the string");
String enc = Convert.ToBase64String(encbuff);

and php side:

$data = $_REQUEST['in'];
$raw = base64_decode($data);

with larger strings 100+ chars it fails. I think this is due to c# adding '+'s in the encoding but not sure. any clues

Dan
  • 29,100
  • 43
  • 148
  • 207
w-ll
  • 3,895
  • 2
  • 31
  • 29
  • Excuse my ignorance, is it necessary to base64 encode a UTF8 string before transferring it? I can see you might need to url encode it. – Jodrell Nov 07 '12 at 09:41

6 Answers6

15

You should probably URL Encode your Base64 string on the C# side before you send it.

And URL Decode it on the php side prior to base64 decoding it.

C# side

byte[] encbuff = System.Text.Encoding.UTF8.GetBytes("the string");
string enc = Convert.ToBase64String(encbuff);
string urlenc = Server.UrlEncode(enc);

and php side:

$data = $_REQUEST['in'];
$decdata = urldecode($data);
$raw = base64_decode($decdata);
Eoin Campbell
  • 43,500
  • 17
  • 101
  • 157
7

Note that + is a valid character in base64 encoding, but when used in URLs it is often translated back to a space. This space may be confusing your PHP base64_decode function.

You have two approaches to solving this problem:

  • Use %-encoding to encode the + character before it leaves your C# application.
  • In your PHP application, translate space characters back to + before passing to base64_decode.

The first option is probably your better choice.

Greg Hewgill
  • 951,095
  • 183
  • 1,149
  • 1,285
  • thanks. yea that + was the problem in the url. did something like this. monkey hacks FTW string enc = Convert.ToBase64String(encbuff).Replace("+", "===="); and $raw = str_replace("====","+",$raw); – w-ll Nov 02 '08 at 22:26
  • 1
    Well, that's one way to do it indeed. What I was suggesting was to replace "+" with "%2B" in the C# application, then you won't have to do anything at all in the PHP application. – Greg Hewgill Nov 02 '08 at 22:28
3

This seems to work , replacing + with %2B...

private string HTTPPost(string URL, Dictionary<string, string> FormData)
{

    UTF8Encoding UTF8encoding = new UTF8Encoding();
    string postData = "";

    foreach (KeyValuePair<String, String> entry in FormData)
    {
            postData += entry.Key + "=" + entry.Value + "&";
    }

    postData = postData.Remove(postData.Length - 1);

    //urlencode replace (+) with (%2B) so it will not be changed to space ( )
    postData = postData.Replace("+", "%2B");

    byte[] data = UTF8encoding.GetBytes(postData); 

    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(URL);

    request.Method = "POST";
    request.ContentType = "application/x-www-form-urlencoded";
    request.ContentLength = data.Length;

    Stream strm = request.GetRequestStream();
    // Send the data.
    strm.Write(data, 0, data.Length);
    strm.Close();

    WebResponse rsp = null;
    // Send the data to the webserver
    rsp = request.GetResponse();

    StreamReader rspStream = new StreamReader(rsp.GetResponseStream());
    string response = rspStream.ReadToEnd();

    return response;

}
cliff
  • 31
  • 1
1

Convert.ToBase64String doesn't seem to add anything extra as far as I can see. For instance:

byte[] bytes = new byte[1000];
Console.WriteLine(Convert.ToBase64String(bytes));

The above code prints out a load of AAAAs with == at the end, which is correct.

My guess is that $data on the PHP side doesn't contain what enc did on the C# side - check them against each other.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
0

The PHP side should be: $data = $_REQUEST['in']; // $decdata = urldecode($data); $raw = base64_decode($decdata);

The $_REQUEST should already be URLdecoded.

0

in c#

this is a <B>long</b>string. and lets make this a3214 ad0-3214 0czcx 909340 zxci 0324#$@#$%%13244513123

turns into

dGhpcyBpcyBhIDxCPmxvbmc8L2I+c3RyaW5nLiBhbmQgbGV0cyBtYWtlIHRoaXMgYTMyMTQgYWQwLTMyMTQgMGN6Y3ggOTA5MzQwIHp4Y2kgMDMyNCMkQCMkJSUxMzI0NDUxMzEyMw==

for me. and i think that + is breaking it all.

w-ll
  • 3,895
  • 2
  • 31
  • 29