2

We are receiving a base64 encoded string from a external application in the form body and below is the code that we are using to decode the string into byte array, however we are getting an exception

Input String

PHBheW1lbnRSZXNwb25zZT48cmVzcG9uc2VDb2RlPjAwMDA8L3Jlc3BvbnNlQ29kZT48cmVzcG9uc2VDb2RlVGV4dD4wLVN1Y2Nlc3NmdWw8L3Jlc3BvbnNlQ29kZVRleHQ+PHJlc3BvbnNlU3VtbWFyeT5HUkVFTjwvcmVzcG9uc2VTdW1tYXJ5PjxwYXltZW50RXZlbnRJZGVudGlmaWVyPlRYTiAzNjM5PC9wYXltZW50RXZlbnRJZGVudGlmaWVyPjxMaXN0Pjxjb21wb25lbnRJRD5UWE4gMzYzOTwvY29tcG9uZW50SUQ+PGNsaWVudElEPkdPVERJU0UwNjwvY2xpZW50SUQ+PGJhbmtBdXRoQ29kZT5UOjEyMzQ8L2JhbmtBdXRoQ29kZT48YnV5bmV0VHhuSUQ+Mzc1PC9idXluZXRUeG5JRD48L0xpc3Q+PHBheW1lbnRJbnN0cnVtZW50UmVmPjwvcGF5bWVudEluc3RydW1lbnRSZWY+PG1hc2tlZENhcmROdW1iZXI+KioqKioqKioqKioqOTY4NjwvbWFza2VkQ2FyZE51bWJlcj48Y2FyZFR5cGU+TUFTVEVSQ0FSRDwvY2FyZFR5cGU+PGV4cGlyeURhdGU+MDMvMjAxNzwvZXhwaXJ5RGF0ZT48Y3VzdG9tRGF0YT4mbHQ7IVtDREFUQVsmbHQ7P3htbCB2ZXJzaW9uPSIxLjAiIGVuY29kaW5nPSJVVEYtOCI_Jmd0Ow0KJmx0O1RoaXN0bGVDdXN0b21EYXRhIHhtbG5zOnhzZD0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEiIHhtbG5zOnhzaT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2UiJmd0Ow0KICAmbHQ7T3JkZXJJZCZndDtCVFBQMzYzOSZsdDsvT3JkZXJJZCZndDsNCiAgJmx0O0Ftb3VudCZndDsxMjAmbHQ7L0Ftb3VudCZndDsNCiZsdDsvVGhpc3RsZUN1c3RvbURhdGEmZ3Q7XV0mZ3Q7PC9jdXN0b21EYXRhPjwvcGF5bWVudFJlc3BvbnNlPg

Exception

The input is not a valid Base-64 string as it contains a non-base 64 character, more than two padding characters, or an illegal character among the padding characters.

Code

var inputText = // use the data as shown above
byte[] decodedBytes = Convert.FromBase64String(inputText);

I want to know what is wrong in this and why it is throwing the exception, where are if i try online converters they are able to return the proper result.

2
  • The input is bad. If I put it into an online decoder I get readable text/xml text up to a point, but then it degenerates into gibberish. It's possible it's mangled by the browser or web server (not correctly http-encoded?) Commented Oct 19, 2016 at 3:43
  • 1
    The error is accurate. Your base64 text includes at least on underscore (_) character, which is invalid. You might try just believing error messages that you get. They are often informative. Replace the _ with + and it will convert correctly. Next time, check your data when you get an error saying your data is invalid. Commented Oct 19, 2016 at 3:45

2 Answers 2

3

Thank you all for the response.

I got this working, after studying how the base64 encoding works.

below is the code that i used to fix it.

var input = new StreamReader(Request.InputStream).ReadToEnd();
        var inputText = "PHBheW1lbnRSZXNwb25zZT48cmVzcG9uc2VDb2RlPjAwMDA8L3Jlc3BvbnNlQ29kZT48cmVzcG9uc2VDb2RlVGV4dD4wLVN1Y2Nlc3NmdWw8L3Jlc3BvbnNlQ29kZVRleHQ+PHJlc3BvbnNlU3VtbWFyeT5HUkVFTjwvcmVzcG9uc2VTdW1tYXJ5PjxwYXltZW50RXZlbnRJZGVudGlmaWVyPlRYTiAzNjM5PC9wYXltZW50RXZlbnRJZGVudGlmaWVyPjxMaXN0Pjxjb21wb25lbnRJRD5UWE4gMzYzOTwvY29tcG9uZW50SUQ+PGNsaWVudElEPkdPVERJU0UwNjwvY2xpZW50SUQ+PGJhbmtBdXRoQ29kZT5UOjEyMzQ8L2JhbmtBdXRoQ29kZT48YnV5bmV0VHhuSUQ+Mzc1PC9idXluZXRUeG5JRD48L0xpc3Q+PHBheW1lbnRJbnN0cnVtZW50UmVmPjwvcGF5bWVudEluc3RydW1lbnRSZWY+PG1hc2tlZENhcmROdW1iZXI+KioqKioqKioqKioqOTY4NjwvbWFza2VkQ2FyZE51bWJlcj48Y2FyZFR5cGU+TUFTVEVSQ0FSRDwvY2FyZFR5cGU+PGV4cGlyeURhdGU+MDMvMjAxNzwvZXhwaXJ5RGF0ZT48Y3VzdG9tRGF0YT4mbHQ7IVtDREFUQVsmbHQ7P3htbCB2ZXJzaW9uPSIxLjAiIGVuY29kaW5nPSJVVEYtOCI_Jmd0Ow0KJmx0O1RoaXN0bGVDdXN0b21EYXRhIHhtbG5zOnhzZD0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEiIHhtbG5zOnhzaT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2UiJmd0Ow0KICAmbHQ7T3JkZXJJZCZndDtCVFBQMzYzOSZsdDsvT3JkZXJJZCZndDsNCiAgJmx0O0Ftb3VudCZndDsxMjAmbHQ7L0Ftb3VudCZndDsNCiZsdDsvVGhpc3RsZUN1c3RvbURhdGEmZ3Q7XV0mZ3Q7PC9jdXN0b21EYXRhPjwvcGF5bWVudFJlc3BvbnNlPg";
        inputText = ValidateBase64EncodedString(inputText);

        byte[] decodedBytes = Convert.FromBase64String(inputText);

        string xml = Encoding.UTF8.GetString(decodedBytes);

       private static string ValidateBase64EncodedString(string inputText)
        {
            string stringToValidate = inputText;
            stringToValidate = stringToValidate.Replace('-', '+'); // 62nd char of encoding
            stringToValidate = stringToValidate.Replace('_', '/'); // 63rd char of encoding
            switch (stringToValidate.Length % 4) // Pad with trailing '='s
            {
                case 0: break; // No pad chars in this case
                case 2: stringToValidate += "=="; break; // Two pad chars
                case 3: stringToValidate += "="; break; // One pad char
                default:
                    throw new System.Exception(
             "Illegal base64url string!");
            }

            return stringToValidate;
        }
0

It's because your custom data is invalid. In that Base64 encoded string you have a raw [CDATA] which is most likely not encoded correctly.

notice that if i take the first 684 characters of your string, it converts properly to:

<paymentResponse><responseCode>0000</responseCode><responseCodeText>0-Successful</responseCodeText><responseSummary>GREEN</responseSummary><paymentEventIdentifier>TXN 3639</paymentEventIdentifier><List><componentID>TXN 3639</componentID><clientID>GOTDISE06</clientID><bankAuthCode>T:1234</bankAuthCode><buynetTxnID>375</buynetTxnID></List><paymentInstrumentRef></paymentInstrumentRef><maskedCardNumber>************9686</maskedCardNumber><cardType>MASTERCARD</cardType><expiryDate>03/2017</expiryDate><customData>&

but all hell breaks loose when we get to the customData tag, this I suppose, contains the CDATA xml content, which is probably not base64 encoded.

So either leave the CDATA content out, or encode it properly before adding it to the final string, to fix the issue

6
  • "this I suppose, contains the CDATA xml content, which is probably not base64 encoded" -- you suppose incorrectly. The XML can be (and probably originally was) encoded just fine even with the CDATA section. Base64 doesn't care what the content is; that's why it works. The only problem is that there's a typo in the base64. Commented Oct 19, 2016 at 17:12
  • @PeterDuniho your comment is incorrect at its base assumption. the letter count of the string he posted is 1,118 characters long, there is no way you can base64 decode a string if its length is not a multiple of 4. replacing one + with one _ will not solve the issue. the CDATA part is messing up the decoding.
    – Stavm
    Commented Oct 19, 2016 at 18:11
  • "your comment is incorrect at its base assumption" -- I assumed nothing. I simply replaced the character as I've indicated, and it decoded fine. It's true that officially, base64 data has to have a character length that's a multiple of 4, but most decoders are tolerant of absent trailing zeroes. The incorrect character length doesn't prevent successful decoding, unless the missing characters were actually non-zero values in the data that got truncated somewhere. Commented Oct 19, 2016 at 20:23
  • 1
    In any case, whatever you think about the length, and whatever decoder you're using, it is patently false that the CDATA section has anything to do with the issue. Base64 can successfully encode whatever data you want, including CDATA sections in XML. It doesn't care what the content is, because it's just encoding the binary representation of whatever your data is. Commented Oct 19, 2016 at 20:24
  • the question was about dot net, so other library tolerance to corrupted input is irrelevant, Convert.FromBase64String() can not work with invalid content. not you nor I know how the string got put together for all we know someone manually typed it. basically we both say the same thing. input was incorrect, I simply pinpointed the fail in the 'customData' tag content. it seems the asker is no longer to be found though so if it worked or not, is still unknown.
    – Stavm
    Commented Oct 19, 2016 at 20:33

Not the answer you're looking for? Browse other questions tagged or ask your own question.