0

I'm using base64 encrypting of html tags due to solve a postback issue with my code. My html tag contain symbols like + , - , / or * . While decrypting the encrypted string im getting the following error :

Invalid length for a Base-64 char array.

Can anybody suggest a workaround here please?

JavaScript Calling from aspx page.

 var keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";

    function encode64(input) {
        var output = "";
        var chr1, chr2, chr3;
        var enc1, enc2, enc3, enc4;
        var i = 0;

        while (i < input.length) {
            chr1 = input.charCodeAt(i++);
            chr2 = input.charCodeAt(i++);
            chr3 = input.charCodeAt(i++);

            enc1 = chr1 >> 2;
            enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
            enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
            enc4 = chr3 & 63;

            if (isNaN(chr2)) {
                enc3 = enc4 = 64;
            }

            else if (isNaN(chr3)) {
                enc4 = 64;
            }

            output += keyStr.charAt(enc1) + keyStr.charAt(enc2) + keyStr.charAt(enc3) + keyStr.charAt(enc4);
        }

        return output;
    }

C# Code to decode the string @ pageload:

 public string DecodeBase64String(string encodedData)
    {
        byte[] encodedDataAsBytes = System.Convert.FromBase64String(encodedData);
        string returnValue = System.Text.ASCIIEncoding.ASCII.GetString(encodedDataAsBytes);

        return returnValue;
    }

Error can be generated by giving a simple string that contain any of the symbols i'd mentioned or even a space character.

Html String :

"<tbody id=\"selectedColumnsTbody\">\n                    <tr style=\"cursor: move;\" id=\"ExprCountryMasterID10\"><td></td><td><input id=\"chk\" checked=\"checked\" class=\"textChangeClass\" type=\"checkbox\"></td><td>CountryMaster.ID + 10</td><td><input id=\"aliastextCountryMasterID10\" class=\"aliasTextChangeClass\" value=\"\" type=\"text\"></td>><td><input id=\"hiddenIDSortCountryMasterID10\" value=\"\" type=\"hidden\"></td></tr></tbody>\n        

Calling decrypt method from cs page:

protected void Page_Load(object sender, EventArgs e) {

        //HtmlTextWriter htmlTable = new HtmlTextWriter();

        //htmlTable.InnerHtml = htmlContent;
        //Master.FindControl("ContentPlaceHolder1").Controls.Add(htmlTable);
        if (Session["HtmlTable"] != null)
        {

            htmlContent = Session["HtmlTable"].ToString();
            //htmlContent = htmlContent.Replace(" ", "+");
            htmlContent = DecodeBase64String(htmlContent);
            htmlTable = new HtmlGenericControl();
            ContentPlaceHolder contentPlaceHolder = (ContentPlaceHolder)this.Master.FindControl("ContentPlaceHolder1");
            if (contentPlaceHolder != null)
            {
                htmlContent = "<table cellspacing=\"0\" cellpadding=\"0\" id=\"selectedColumns\" width=\"100%\">" + htmlContent + "</table>";
                htmlTable.InnerHtml = htmlContent;
                test.InnerHtml = htmlContent;
            }
        }

}

Javascript where im calling htmlEncode function StoreSessionForHtml(htmlContent) {

        //            var encodedObject = htmlEncode(htmlContent);
        //            var decodedObject = htmlDecode(encodedObject);
        //htmlContent = htmlContent.replace(/ /g, "+");


        var encodedObject = encode64(htmlContent);

        var requesthtmlContentParameter = '{' +
                        'htmlContentToServer:"' + encodedObject + '"}';

        $.ajax({
            type: "POST",
            url: "Webtop.aspx/HTMLTableContent",
            data: requesthtmlContentParameter,
            contentType: "application/json; charset=utf-8",
            dataType: "json",
            success: function(msg) {
                //alert("Success", msg.d);
            }, //Event that'll be fired on Success
            error: function() {
               // alert("Try Again");

            } //Event that'll be fired on Error
        });
        $("#<%= HiddenHtmlContainer.ClientID %>").val(encodedObject);
    }
NewBie
  • 1,824
  • 8
  • 35
  • 66
  • Please add some more detail, it will good if you add code. – BreakHead Jun 02 '11 at 11:59
  • Please add the code snippets of what/how you are doing it – mkilmanas Jun 02 '11 at 11:59
  • Also if you want to let us know what some of your values are in the code (eg string you are encoding and what it encodes to) then we might be able to do more debugging if answers below weren't sufficient. – Chris Jun 02 '11 at 12:37
  • It's a table with a column containing a text like a + 10 or something. – NewBie Jun 02 '11 at 12:51
  • How does the encoded string get into the Session? – GalacticCowboy Jun 02 '11 at 13:14
  • Setting it using json object. – NewBie Jun 02 '11 at 13:15
  • So in your JS if you set `htmlContent=' '` then `alert(encodedObject)` will display "+" is what you are saying in comments to answers? – Chris Jun 02 '11 at 14:01
  • @Chris . Yes, that's how i got + sign – NewBie Jun 03 '11 at 02:50
  • @NewBie: there is something very wrong then. the output variable in your method *must* be a multiple of four characters because the only place the output variable is written it writes four characters. I'd suggest trying a) to copy that function into a test page and trying it again and b) checking that you definitely haven't got any other functions called the same thing that might be throwing it off. If you have a javascript debugger I'd get that running and trace through the execution path. Your call to encode64 definitely seems to be the core of your problem. – Chris Jun 03 '11 at 08:35
  • Working on it Chris. Dont even know whether there is anything wrong with my way of decoding it. The string im getting encoded from the javascript is decrypted the way it was in most of the online base 64 encode/decode sites. – NewBie Jun 03 '11 at 08:54
  • 1
    If you are getting "+" out of the javascript then that should definitely not be getting decoded at all in any online base64 decoder. – Chris Jun 03 '11 at 15:05
  • You're passing a string as your POST data, not a JSON object. I'm no AJAX expert, but that looks... weird. – GalacticCowboy Jun 03 '11 at 18:02

2 Answers2

0

Why don't use the HttpUtility.HtmlEncode Method

to prevent attack

Sergey K
  • 4,071
  • 2
  • 23
  • 34
  • Becuase he is encoding in javascript, not a .net language. – Chris Jun 02 '11 at 12:15
  • Encryption is done at the client side. Is there anything similar to this i can use @ the client side? – NewBie Jun 02 '11 at 12:19
  • @newBie: http://stackoverflow.com/questions/246801/how-can-you-encode-to-base64-using-javascript . This seems to suggest that you are doing it as well as you can since that looks like the function you are using. :) – Chris Jun 02 '11 at 12:25
  • @serghei: Also I'm not sure that Html Encoding will actually particularly help anyway. It can as easily be done server side for a start once he has the transfer going and I'm not sure actually has any relationship to his problems with Base64 encoding and decoding... – Chris Jun 02 '11 at 12:26
  • I take back my previous comment. I assume you were suggesting that rather than using Base64 to get round the issue of passing HTML tags that he html encodes it all before sending to server and decodes it when getting there. This could potentially work but it may depend on why base64 encoding was chosen for this... – Chris Jun 02 '11 at 13:03
  • Because my inputs are kept in an html table and i'm sending it as a whole to the server. Clientside validation is more easier than making the data hit the server 100times. That's why. – NewBie Jun 02 '11 at 13:08
0

There shouldn't be any problems with encoding any character since you are not encoding characters, you are encoding bytes.

The error you are getting I would assume is due to the legnth of your base64 encoded string not being correct. Base 64 encoding effectively changes groups of three bytes into groups of four characters. This means that decoders will want a string to decode that is a multiple of four characters. This is achieved by using the special character "=" to pad it out. This allows the decoder to know that those bytes don't exist (as opposed to just being blank or indeed missing).

The chances are that you had a problem purely because of the number of characters in the string you were decoding.

http://base64encode.org/ may be helpful for validating the strings you are generating to check whether your problem is with the encoding or decoding.

Chris
  • 27,210
  • 6
  • 71
  • 92
  • Yeah, his script is identical to other resources online. I've been testing it with a console app and HTML file and can't seem to break it. @NewBie, is there a way to ensure that your string isn't getting mangled in transit? – GalacticCowboy Jun 02 '11 at 12:49
  • It's doing good with plain texts and i made it sure by encoding a single space character and it throws the error. – NewBie Jun 02 '11 at 12:52
  • I just copied your code directly into a console app and HTML page; used the page to encode a value and then passed it to the console app. It decoded fine. I tried a bunch of variations, such as "A + b - c = D". – GalacticCowboy Jun 02 '11 at 12:59
  • If you are debugging in C# can you confirm what the string being passed to your decode method is? Also how are you passing it? Some of the base 64 characters may cause problems if you are putting them in a querystring since they can have special meanings there... This may mean that by the time you are extracting them they aren't quite what you thought you were putting in... – Chris Jun 02 '11 at 12:59
  • When you encode the string containing a space, what value do you get? The encoded string should be "IA==". Then, verify that's exactly what you've got going into the decode method. – GalacticCowboy Jun 02 '11 at 13:00
  • Can you post the code that makes the call to DecodeBase64String(string encodedData)? I suspect you may not be parsing the data that is posted to your page correctly. Are you processing the querystring directly? – DaveRead Jun 02 '11 at 13:10
  • @GalacticCowboy, that's what i got using the above javascript. – NewBie Jun 02 '11 at 13:14
  • HUH??? You passed a single space (" ") to your Javascript and got "+"? Because I did exactly the same thing, using your method (copy/pasted), and got "IA==". Yours isn't even a valid Base64 string. – GalacticCowboy Jun 02 '11 at 13:17
  • Yea, that's what i got. Dont know why. – NewBie Jun 02 '11 at 13:20
  • Then you need to look at your web form and make sure it's actually running through the encoder and not doing some kind of JSON encoding instead. – GalacticCowboy Jun 02 '11 at 13:21
  • The content type i'm using is charset=utf-8 in the json object. Dont know anything wrong with this. – NewBie Jun 02 '11 at 13:27
  • @Newbie: looks like its a problem in your javascript then so you might want to show us how you are calling your javascript method to do the base64 encoding... – Chris Jun 02 '11 at 13:37