Base64 encode a javascript object - javascript

I have large Javascript objects which I would like to encode to base-64 for AWS Kinesis`
It turns out that:
let objStr = new Buffer(JSON.stringify(obj), 'ascii');
new Buffer(objStr, 'base64').toString('ascii') !== objStr
I'm trying to keep this as simple as possible.
How can I base-64 encode JSON and safely decode it back to its original value?

From String to Base-64
var obj = {a: 'a', b: 'b'};
var encoded = btoa(JSON.stringify(obj))
To decode back to actual
var actual = JSON.parse(atob(encoded))
For reference look here.
https://developer.mozilla.org/en/docs/Web/API/WindowBase64/Base64_encoding_and_decoding

You misunderstood the Buffer(str, [encoding]) constructor, the encoding tells the constructor what encoding was used to create str, or what encoding the constructor should use to decode str into a byte array.
Basically the Buffer class represents byte streams, it's only when you convert it from/to strings that encoding comes into context.
You should instead use buffer.toString("base64") to get base-64 encoded of the buffer content.
let objJsonStr = JSON.stringify(obj);
let objJsonB64 = Buffer.from(objJsonStr).toString("base64");

When converting object to base64 I was getting out of latin range issues and character invalid error.
I made it work in my project with the below line.
Include the base64 and utf8 node packages and access them like this:
var bytes = base64.encode(utf8.encode(JSON.stringify(getOverviewComments())));

You can easily encode and decode from and to JSON/Base64 using a Buffer:
JSON to Base64:
function jsonToBase64(jsonObj) {
const jsonString = JSON.stringify(jsonObj)
return Buffer.from(jsonString).toString('base64')
}
Base64 to JSON:
function encodeBase64ToJson(base64String: string) {
const jsonString = Buffer.from(base64String,'base64').toString()
return JSON.parse(jsonString)
}
atob() and btoa() are outdated and should no longer be used.

Related

ABAP string to SHA256 different to SAPUI5/Javascript

Currently on my SAPUI5 project, I am creating a HMAC encoded string with this line of code:
var secretKey = CryptoJS.enc.Hex.parse('SECRETKEY'); //USING THE CRYPTOJS LIBRARY!
var hash = CryptoJS.HmacSHA256('abc', secretKey);
hashInBase64 = CryptoJS.enc.Base64.stringify(hash);
which gives eZdbNMwgWKOANEiozokNG2FGfzI7Yy/B8IQKXr3+krY=
I am using the CryptoJS library to execute this code in UI5.
However the problem is that I am receiving the wrong HMAC encoded string when I want to do the same in ABAP. After testing a few times, it seems like the encoding (in abap) is wrong before the HMAC is calculated.
Is there a function module that does 'CryptoJS.enc.Hex.parse()' - after googling what it does it interprets the parameter as encoded and converts it into a word array:
DATA:
lv_sign_key_x TYPE xstring,
lv_hmac_result TYPE string.
DATA(lv_binary_secret) = cl_abap_hmac=>string_to_xstring('SECRETKEY').
cl_abap_hmac=>calculate_hmac_for_char(
EXPORTING
if_algorithm = 'SHA256' "Hash Algorithm
if_key = lv_binary_secret "HMAC Key
if_data = 'abc' "Data
IMPORTING
ef_hmacb64string = lv_hmac_result "HMAC value as base64-encoded string
).
which gives 9dyEZn5G+uiRwsNqgY5S6k9/gmCheFNF4vFa5qBKK1w=
Shows exact way to encode to hex and calculate to HMAC256. Link
data lv_binary_secret type xstring.
data lv_string type string value '48656c6c6f2c20576f726c6421'.
translate lv_string to upper case.
lv_binary_secret = lv_string.
cl_abap_hmac=>calculate_hmac_for_char(
EXPORTING
if_algorithm = 'SHA256' "Hash Algorithm
if_key = lv_binary_secret "HMAC Key
if_data = 'abc' "Data
IMPORTING
ef_hmacb64string = data(lv_hmac_result) "HMAC value as base64-encoded string
).`enter code here`

Replicate BTOA Javascript Function in SAS Data Step

When I encrypt the string g.b#yahoo.it in Javascript using the BTOA function I get the result Zy5iQHlhaG9vLml0.
This function converts the string to the base64 representation of the string. When I try and do the equivalent in SAS I get a different value:
proc fcmp outlib=common.funcs.funcs;
function b64(string $) $;
length digest $32767;
digest=strip(put(string,$base64x32767.));
return(digest);
endsub;
quit;
data email;
input email $12.;
datalines;
g.b#yahoo.it
run;
data X;
set email;
e1 = "<" || trim(email) || ">";
pw_e = b64(e1);
put _all_;
run;
Gives me:
email=g.b#yahoo.it e1=<g.b#yahoo.it> pw_e=PGcuYkB5YWhvby5pdD4= _ERROR_=0 _N_=1
Based on the documentation for each, they are using the same alphabet:
http://support.sas.com/documentation/cdl/en/lrdict/64316/HTML/default/viewer.htm#a003161924.htm
https://www.w3schools.com/jsref/met_win_btoa.asp
I want to replicate the same function in SAS Data Step to obtain the same result. Is there a way to do this in SAS?
They are doing the same thing. You are modifying the string that you are passing to the base64 encoding function in SAS which is why you are getting a different result. The string you are using in SAS is <g.b#yahoo.it> (you added the < and > characters around it.
If you run that same string of <g.b#yahoo.it> through btoa() you get the same result of PGcuYkB5YWhvby5pdD4=

node encode and decode utf-16 buffer

im working on a javascript/nodejs application that needs to talk with a C++ tcp/udp socket. It seems like I get from the old C++ clients an utf16 buffer. I didn't found a solution right now to convert it to a readable string and the other direction seems to be the same problem.
Is there a easy way for this two directions?
Nice greetings
If you have a UTF-16-encoded buffer, you can convert it to a UTF-8 string like this:
let string = buffer.toString('utf16le');
To read these from a stream, it's easiest to use convert to string at the very end:
let chunks = [];
stream.on('data', chunk => chunks.push(chunk))
.on('end', () => {
let buffer = Buffer.concat(chunks);
let string = buffer.toString('utf16le');
...
});
To convert a JS string to UTF-16:
let buffer = Buffer.from(string, 'utf16le')

How can I obfuscate a string in JavaScript?

Basically, I want to make a game in JavaScript and allow a user to get a copy paste-able code which stores their data. In reality, this "code" is actually obfuscated JSON that can be decoded by the application later.
I don't need much security, as I am aware that if people put some effort in they can view/modify the save, and I have no interest in stopping them. I just want the average user to not be tempted and/or see unnecessary information.
Thanks in advance.
you can use base64 encoding to encode your json String. it would be faster approach.
If you with pure javascript :
var encodedData = btoa("stringToEncode");
If you are using nodejs:
base-64 encoding:
var encodedStr = new Buffer("Hello World").toString('base64')
decode to original value:
var originalString = new Buffer("SGVsbG8gV29ybGQ=", 'base64').toString('utf-8')
Well... given that there is no security concern and you only want users to see what appears to be garbled data you can "encode" all the json data
var jsonData = {"key":"value"};
// turn it into a string
var jsonString = JSON.stringify(jsonData);
// replace some letters
var awkardString = jsonString.replace(/a/g, '!Ax6'); // be carefull, you should replace a letter with a pattern that does not already exist on the string.
// encode it with some type of reversible encoding
var garbledData = encodeURI(jsonString);
// output is: %7B%22key%22:%22v!Ax6lue%22%7D
// to "decode" it do the same steps in reverse
awkardString = decodeURI(garbledData);
jsonString = awkardString.replace(/!Ax6/g, 'a'); // now you see, if '!Ax6' existed on the source string, you would loose it and get an 'a' in return. That is why the replacement should be as unique as possible
jsonData = JSON.parse(jsonString);

How do I store a javascript string in byte format and for later retrieval in string form?

I want to generate a file containing strings alongside Float32Arrays in my web app. I can write this data into a blob and then a file like this:
var myFirstFloat32Array = new Float32Array([42, 1, 2, 3]);
var myString = 'This is my string. It is a beautiful string.';
var blob = new Blob([
new Uint8Array([myFloat32Array.length]), // Store the size.
myFloat32Array,
new Uint8Array([myString.length]), // Store the size.
myString);
var downloadLink = document.createElement('a');
downloadLink.href = window.URL.createObjectURL(blob);
downloadLink.download = 'generatedFile';
downloadLink.innerHTML = 'Click to download generated file.';
So ... that successfully writes the file, but how do I read the string following the float 32 array?
I can read the first float32 array easily by reading the number from the first 4 bytes (which gives me the size of the array) and then constructing a Float32Array of that length.
However, how do I read the string? The string could contain characters outside of the ASCII range, so I can't just btoa the string, convert to a Uint8Array, and then write it.
Maybe I could convert the string to a blob first, get its size from the blob, and then somehow decode it later while reading (but how do I know the character encoding used later)?
What's the standard way to store string data alongside byte data in javascript for later decoding?

Categories