Unable to decode base64 from req.header.authorization - javascript

In express I am grabbing the basic auth from:
req.headers.authorization
From that I get back
dXNlcm5hbWU6cGFzc3dvcmQ=
I say "hey that looks like base64". I quickly go to one of those base64 sites and decode it and it turns out to be 'username:password'. So I google how to decode base64 in express 4. I wind up with this code:
console.log(new Buffer(req.headers.authorization.toString(), 'base64').toString('ascii'));
That is returning:
+"qUMI95iAMM]=I
Which is not username:password. I also tried this with the utf8 setting and that did not work either. I also tried this without toString() on the req.headers.authorization. How do I properly decode base64 with expressjs?

In case anyone is as stupid as I am and didn't realize that the string that is returned from req.headers.authorization is the word Basic followed by the base64 encoded string, you must split the string before decoding.
console.log(new Buffer(req.headers.authorization.split(" ")[1], 'base64').toString())
req.headers.authorization returned for me: Basic dXNlcm5hbWU6cGFzc3dvcmQ=. Not just the base64 string.

Using the new Buffer API it is now
console.log(Buffer.from(req.headers.authorization.split(" ")[1], 'base64').toString())
Else you will get deprecated warnings.

Related

Decoding Base64 String in Java

I'm using Java and I have a Base64 encoded string that I wish to decode and then do some operations to transform.
The correct decoded value is obtained in JavaScript through function atob(), but in java, using Base64.decodeBase64() I cannot get an equal value.
Example:
For:
String str = "AAAAAAAAAAAAAAAAAAAAAMaR+ySCU0Yzq+AV9pNCCOI="
With JavaScript atob(str) I get ->
"Æ‘û$‚SF3«àö“Bâ"
With Java new String(Base64.decodeBase64(str)) I get ->
"Æ?û$?SF3«à§ö?â"
Another way I could fixed the issue is to run JavaScript in Java with a Nashorn engine, but I'm getting an error near the "$" symbol.
Current Code:
ScriptEngine engine = new ScriptEngineManager().getEngineByName("JavaScript");
String script2 = "function decoMemo(memoStr){ print(atob(memoStr).split('')" +
".map((aChar) => `0${aChar.charCodeAt(0).toString(16)}`" +
".slice(-2)).join('').toUpperCase());}";
try {
engine.eval(script2);
Invocable inv = (Invocable) engine;
String returnValue = (String)inv.invokeFunction("decoMemo", memoTest );
System.out.print("\n result: " + returnValue);
} catch (ScriptException | NoSuchMethodException e1) {
e1.printStackTrace();
Any help would be appreciated. I search a lot of places but can't find the correct answer.
btoa is broken and shouldn't be used.
The problem is, bytes aren't characters. Base64 encoding does only one thing. It converts bytes to a stream of characters that survive just about any text-based transport mechanism. And Base64 decoding does that one thing in reverse, it converts such characters into bytes.
And the confusion is, you're printing those bytes as if they are characters. They are not.
You end up with the exact same bytes, but javascript and java disagree on how you're supposed to turn that into an ersatz string because you're trying to print it to a console. That's a mistake - bytes aren't characters. Thus, some sort of charset encoding is being used, and you don't want any of this, because these characters clearly aren't intended to be printed like that.
Javascript sort of half-equates characters and bytes and will freely convert one to the other, picking some random encoding. Oof. Javascript sucks in this regard, it is what it is. The MDN docs on btoa explains why you shouldn't use it. You're running into that problem.
Not entirely sure how you fix it in javascript - but perhaps you don't need it. Java is decoding the bytes perfectly well, as is javascript, but javascript then turns those bytes into characters into some silly fashion and that's causing the problem.
What you have there is not a text string at all. The giveaway is the AA's at the beginning. Those map to a number of zero bytes. That doesn't translate to meaningful text in any standard character set.
So what you have there is most likely binary data. Converting it to a string is not going to give you meaningful text.
Now to explain the difference you are seeing between Java and Javascript. It looks to me as if both Java and Javascript are making a "best effort" attempt to convert the binary data as if is was encoded in ISO-8859-1 (aka ISO LATIN-1).
The problem is some of the bytes codes are mapping to unassigned codes.
In the Java case those unassigned codes are being mapped to ?, either when the string is created or when it is being output.
In the Javascript case, either the unassigned codes are not included in the string, or them are being removed when you attempt to display them.
For the record, this is how an online base64 decoder the above for me:
����������������Æû$SF3«àöBâ
The unassigned codes are 0x91 0x82 and 0x93. 0x15 and 0x0B are non-printing control codes.
But the bottom line is that you should not be converting this data into a string in either Java or in Javascript. It should be treated as binary; i.e. an array of byte values.
byte[] data = Base64.getDecoder().decode(str);

Decode JavaScript btoa() encoded string using Java/Kotlin Base64 decoder

I have an encoded string as follows:
S0VEQUkgUlVOQ0lUIFZSSU5FIEVOVEVSUFJJU0UgLSBLRyBTSU1QQU5HIDQgU09PSw
This was encoded using JavaScript btoa() function. This string can be correctly decoded using JavaScript atob() function. It should give the following decoded string :
KEDAI RUNCIT VRINE ENTERPRISE - KG SIMPANG 4 SOOK
Right now I'm developing Android app and I have to decode this string, I'm using the following to decode :
java.util.Base64.getDecoder().decode(encodedstring).toString();
I'm not getting the correct decoded output. Anyone knows what's the problem ? Is it even possible to decode using Java ?
decode(String) returns a byte[], you need to convert that to a string using a String constructor and not the toString() method:
byte[] bytes = java.util.Base64.getDecoder().decode(encodedstring);
String s = new String(bytes, java.nio.charset.StandardCharsets.UTF_8);
It looks like you need mime decoder message
java.util.Base64.Decoder decoder = java.util.Base64.getMimeDecoder();
// Decoding MIME encoded message
String dStr = new String(decoder.decode(encodedstring));
System.out.println("Decoded message: "+dStr);

Base64 encoding fails for non-latin characters

I'm working on a VueJS project where I generate SVG images based on input. After they have been generated, I send data from them to a back end API as a base64 encoded string.
Now, whenever I try to encode the string with UTF8 characters, I get the following error:
Uncaught DOMException: Failed to execute 'btoa' on 'Window': The string to be encoded contains characters outside of the Latin1 range.
I tried to solve the issue with replacing all characters in the HTML with their Unicode code points. However, whenever I try to get the DOM element, the Unicode encoded characters are reverted back to their plain text format.
How can I obtain the HTML as a base64 encoded string?
The issue can be seen in a fiddle here.
I've tried both using XMLSerializer and just running innerHTML.toString():
let svgEl = this.$el.querySelector('.svg-container svg')
if (!svgEl) {
console.log('no poster element')
return
}
// Using XMLSerializer:
console.log(btoa(new XMLSerializer().serializeToString(posterEl))
// Using innerHTML:
console.log(btoa(posterEl.innerHTML.toString()))
Both the above examples yield the same error.
Thanks.
You can follow the answer steps in for this answered question:
Failed to execute 'btoa' on 'Window': The string to be encoded contains characters outside of the Latin1 range.
The key of solution is to encode the string by this way:
btoa(unescape(encodeURIComponent(str)));

What is that nonsense string we get when requesting binary data, and how do we convert it into a proper buffer?

When using a library to request some non-ASCII/UTF8 data, we often get back a string full of nonsense. Example:
const got = require("got");
got("http://twemoji.maxcdn.com/16x16/1f525.png")
.then(response => console.log(response.body))
This is the output:
�PNG
IHD��aaIDAT8�c`��L�fEb��?��8�-���#���5�!� ���|bQ\�$�� �ׁX�y�xT
���y#< �c�i��6$�K$
L÷���w��������_��Ϡ���d��?�j��2��� ��hX��cn������e"L����x�3�
��Y�f�N���
mt:����2e�f��N���~{'̀x�ȿ �;�m
�
�PIEND�B`� �vZ�]�dX<R�\�Y:������`�A�A��ӂƟ}�����#A�\�n����|�A� u83����,�{������#�#4��#��D�
Curiously, that is the same thing we see when downloading the image and using:
cat 1f525.png
What, exactly, is that string, why it looks like this, and how do we convert it to a proper Buffer object?
That's a PNG image which is not text data, but just basic binary data. It doesn't make sense to interpret it as a string.
got will return string, buffer, readableStream, or object. console.log is converting your stream into a string which is not what you want. cat deals with text, not binary data.
Also the response from http://twemoji.maxcdn.com/16x16/1f525.png does not include the Content-Type header which could be throwing off the got library.
It's not really strange that you see the same output from cat - that is how a PNG image looks like when interpreted as a string.
According to the got documentation, it should return a buffer when you specify the encoding as null. Perhaps console.log is converting the buffer to a string, or you could try to set the encoding to image/png.
Did you actually try to save to image to file? Perhaps it'll just work.
By default, got will fetch you a string. It assumes you want UTF-8 text data by default, since that's probably the most common case, people fetching HTML documents. From the documentation:
encoding
Type: string, null
Default: 'utf8'
Encoding to be used on setEncoding of the response data. If null, the body is returned as a Buffer.
If you want binary data instead, specify {encoding: null}:
const got = require("got");
got("http://twemoji.maxcdn.com/16x16/1f525.png", {encoding:null})
.then(response => console.log(response.body))
Then response.body will be a Buffer.

convert binary data to base-64 javaScript

I have a problem to convert binary data to base-64 in JS.
I try all the things that exists on the net include this How to parse into base64 string the binary image from response?, but everyone return a wrong base-64 and I don't find why !
**I try this solution Retrieving binary file content using Javascript, base64 encode it and reverse-decode it using Python but the convert to base-64 not work for me! It's return something wrong .
I get a string binary response from server and I want to convert him to base-64 that I can create a file from him and to show him to user.
This is the response I get from server to png picture for example:
�PNG
IHDRrP6�tEXtSoftwareAdobe ImageReadyq�e<�IDATx�b���?�#6��g��T=;��� >č�&g��:��A�#���LX��0�A�T >[40f��H��>0`B
#��<��0a�+���b�
�o����­o0��~�7��'�xlP����e��.3<x��A�����~�w��$�#90���
`���Ivd�1#c�2���F&�ATM��.�p���[���8��p�]�#,�����pyP��q���pB����u�����3l(6A `#􁳟qzK�Q���M�8Q�Ӑ&��1�$(�#� R�81H��P�&P�����ҟ1\��V��3P�d��fp0�#;��ld �yt�(����
J{�М��>>#{!А�3%?#/�
0�O�U,{�9IEND�B`�
Now , I want to take this binary string and to convert him .
For example , the real base 64 of png picture is:
iVBORw0KGgoAAAANSUhEUgAAABMAAAATCAYAAAByUDbMAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAaJJREFUeNpi/P//PwO1ACM2wf9njBWAVD0QOwCxApLUAyA+AMSNjCZnH6DoATqKEYtB/UCqgAiHTAAaWIjTMKBB84FUAgk+WwA0MBFmGBOaixJIDKYEqD4wYEIKI7DXHjz/xTBh+SuGD5//YtUNkm+c9Zzhwq1vMKECqH6IN5G9J+h4AWxQgIMAw/oeZQzDFP0uMzx49otBgJeZ4f1+A7h3GYzPJLJAOQEw0fn1CmCFuADIAgVJdmSXMUBjHe4yyhOb8RlGJqBBDlRNtMgu23DgA8PFW98Z9NU4weGGDnDKA10GC7MPQCwAiqnAkrtweVDYGahxwfmgcEKO5fubdYHhxwbTzwAzbAMoNkESIANgGkD0gbOfcXpLgAceURvg6QwIFsITTaQ4UeHTkCaFHOsLMfIkKOxAuCBSDBSGODFIHqYWlgNQ8iZQEBSa+4HYAJHSnzFcuPkdHFagsDNQ52SI9xFmcDDmhQcjEDsC8+cHbBkdZCCxeXQCtCj6gLMIghoKSnvx0JyBnD4+QAN7IdCQAwTLMxwFJQg/QC8Q0Q0DCDAA/k/PVSx73TkAAAAASUVORK5CYII=
When I use any kind of code to convert to base-64 it's return this string :
77+9UE5HDQoaCgAAAA1JSERSAAAAEwAAABMIBgAAAHJQNu+/vQAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHvv71lPAAAAe+/vUlEQVR477+9Yu+/ve+/ve+/vT8D77+9ACM277+977+9Z++/vRXvv71UPRA7AO+/vQLvv73vv70DID4AxI3vv70mZx/vv73vv70BOu+/vRHvv71B77+9QO+/ve+/vQjvv71MABpY77+977+9MO+/vUHvv73vv71UAgk+WwA0MBFmGBPvv73vv70SSAzvv70E77+9PjBgQgoj77+977+9Hjzvv73vv70wYe+/vSvvv70P77+977+9Yu+/vQ3vv71v77+977+977+977+9wq1vMO+/vQLvv71+77+9N++/ve+/vSfvv714AWxQ77+977+9AO+/ve+/vR5lDO+/vRTvv70uMzx477+977+9Qe+/ve+/ve+/ve+/ve+/vX4D77+9dxnvv73vv70k77+9QDkBMO+/ve+/ve+/vQpg77+977+9AO+/vQIFSXZk77+9MUBjHe+/vTLvv70T77+977+9GUYm77+9QQ5UTe+/ve+/vS7vv71w77+9A++/ve+/vVvvv70Z77+977+9OO+/ve+/ve+/vQ5w77+9A10GC++/vQ9ALADvv73vv73vv73vv73vv71weVDvv70Z77+9ce+/ve+/ve+/vXBC77+977+977+977+9de+/ve+/ve+/vQbvv73vv70AM2wDKDZBEiADYBpA9IGzn3F6S++/vQceURvvv73vv70MCBbvv70TTe+/vThR77+905Am77+9HO+/vQsx77+9JCjvv71A77+9IFIMFO+/vTgxSB7vv70W77+9A1Dvv70mUBAU77+977+977+977+9AO+/vdKfMVzvv73vv70dHFbvv73vv70zUO+/vWTvv73vv70RZnAw77+977+9ByMQOwLvv73vv70HbBkdZCDvv715dALvv70o77+977+977+9CO+/vRoKSnvvv73QnO+/ve+/vT4+QAN7IdCQAwTvv70zHAUlCD9ALxDvv70NAwgwAO+/vU/vv71VLHvvv705AAAAAElFTkTvv71CYO+/vQ==
I find this solution for encode to base 64 : https://koding.com/Activity/base64-encoding
And now the encode is closer to what need to be but still not help:
/VBORw0KGgoAAAANSUhEUgAAABMAAAATCAYAAAByUDb9AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5cf1lPAAAAf1JREFUeP1i/f39PwP9ACM2/f1n/RX9VD0QOwD9Av39AyA+AA39Jmcf/f0BOv0R/UH9QP39CP1MABpY/f0w/UH9/VQCCT5bADQwEWYYE/39EkgM/QT9PjBgQgoj/f0ePP39MGH9K/0P/f1i/Q39b/39/f2tbzD9Av1+/Tf9/Sf9eAFsUP39AP39HmUM/RT9LjM8eP39Qf39/f39fgP9dxn9/ST9QDkBMP39/Qpg/f0A/QIFSXZk/TFAYx39Mv0T/f0ZRib9QQ5UTf39Lv1w/QP9/Vv9Gf39OP39/Q5w/QNdBgv9D0AsAP39/f39cHlQ/Rn9cf39/XBC/f39/XX9/f0G/f0AM2wDKDZBEiADYBpAx99xekv9Bx5RG/39DAgW/RNN/ThR/dAm/Rz9CzH9JCj9QP0gUgwU/TgxSB79Fv0DUP0mUBAU/f39/QD9nzFc/f0dHFb9/TNQ/WT9/RFmcDD9/QcjEDsC/f0HbBkdZCD9eXQC/Sj9/f0I/RoKSnv9HP39Pj5AA3shEAME/TMcBSUIP0AvEP0NAwgwAP1P/VUse/05AAAAAElFTkT9QmD9
I try also the soultions here:https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Sending_and_Receiving_Binary_Data without convert to base-64 and with 'arrayBuffer' and 'Blob' objects but the picture didn't show . The only way the picture show it's when I convert to a correct base-64 and then create arraybuffer and initialize Blob with him .
But the problem is the same - I cant convert my data to correct base-64.
can anyone save me please ??
Thanks !
Here is the link to this small library that is meant can be useful for u. It can convert base64 to binary and vice versa.
My problem is solved . I use dropzone plugin to get the response from server and because of this I get binary data as a text reponse and it make my problems. I just go to dropzone.js and change 2 minor things to get the response in type of arraybuffer :
xhr.responseType = 'arraybuffer'; ( line 1246)
This is new line to get the response in type of arrayBuffer, and then create a Blob object from the arraybuffer response .
response = xhr.response; (line 1305 )
Change it to get response inseted TextRrsponse..
I hope that it will help somebody...
Thanks everyone !
You could try using the turbocommons library. Just download the minified js file (turbocommons-es5.zip) and write the following code:
<script src="../yourpathtothelibrary/turbocommons-es5.js"></script>
<script>
var ConversionUtils = org_turbocommons.ConversionUtils;
ConversionUtils.stringToBase64('your binary string here');
</script>
I believe it will work in your case as it is extensively tested, Or you can look at the code on how it is done by the library here:
https://github.com/edertone/TurboCommons/blob/master/TurboCommons-TS/src/main/ts/utils/ConversionUtils.ts
More info here:
https://turboframework.org/en/blog/2022-10-26/encode-decode-base64-strings-javascript-typescript-php
Or you can test it online here:
https://turboframework.org/en/app/stringutils/base64-encode

Categories

Resources