unable to get the value of decoded base64 data in node - javascript

this value was encoded to base64
{
a: "008078888658936",
b: "REA"
}
and was decoded using this code
var mytokenvalue = "ewphOiAiMDA4MDc4ODg4NjU4OTM2IiwKYjogIlJFQSIKfQ=="
let decoded = Buffer.from(token, 'base64')
meanwhile, when I try to get the decoded value
console.log(decoded.a)
I am getting undefined in my console.
Please help

You may need to return the decoded value as a string with .toString().
let token = "ewphOiAiMDA4MDc4ODg4NjU4OTM2IiwKYjogIlJFQSIKfQ==";
let decoded = Buffer.from(token, 'base64').toString();
console.log(decoded);

You could do:
var token = "ewphOiAiMDA4MDc4ODg4NjU4OTM2IiwKYjogIlJFQSIKfQ==";
eval('var decoded = ' + Buffer.from(token, 'base64').toString());
console.log(decoded.a);
But eval is extremely dangerous if the base64-encoded string can come from somewhere that is outside your control. An arbitrary string could expand to some unexpected JavaScript that would cause eval to do something that would make your program misbehave or breach security.
It would be better to express the original object as a JSON string (use JSON.stringify to do that) and base64-encode that string. Then you can use JSON.parse to reconstruct the original object without taking on the risk of using eval. Like this:
var obj = { x: "foo", y: 123 };
var obj_json = JSON.stringify(obj);
// obj_json is '{"x":"foo","y":123}'
var obj_b64 = Buffer(obj_json).toString('base64');
// obj_b64 is 'eyJ4IjoiZm9vIiwieSI6MTIzfQ=='
var decoded = JSON.parse(Buffer.from(obj_b64, 'base64').toString());
console.log(decoded.x);

Related

Confused on how to implement HMACSHA1 in C# .NET coming from javascript

I am using the crypto-js library to implement the HMACSHA1 for my javascript code
the code looks like this
const hash1 = require("crypto-js");
let signature = "application_id=3610&auth_key=aDRceQyTXSYEdJU&nonce=6304033672&timestamp=1623098533&user[login]=john#mail.com&user[password]=123456789"
let key = "dBV2PdhYMnruSMb"
let hash = hash1.HmacSHA1(signature, key).toString()
console.log(hash)
//which prints
467280c4cb82fc97bd04c51d8a846446ad6e82e1
this obviously is pretty easy in javascript. But then I tried using the same exact string and key in c# and it prints out a completely different string. I am lost and don't know how to solve this issue.
Here is my attempt to implement this in C#
string signSession = "application_id=3610&auth_key=aDRceQyTXSYEdJU&nonce=6304033672&timestamp=1623098533&user[login]=john#mail.com&user[password]=123456789"
string key = "dBV2PdhYMnruSMb="
//convert the session signature string to a byte array
byte[] signature = Encoding.UTF8.GetBytes(signSession.ToString());
var apiKey = Convert.FromBase64String(key);
//Generate a HMACSHA1 signature
using(HMACSHA1 hmac = new HMACSHA1(apiKey))
{
byte[] signatureBytes = hmac.ComputeHash(signature);
string base64Signature = Convert.ToBase64String(signatureBytes);
Console.WriteLine(base64Signature);
session.Signature = base64Signature;
}
//And this prints
sztTnSTv2xvuA7pPXxk2cKMP0Eo=
//which is wrong. It should be the same as the javascript result
Im not sure what im doing wrong here and is my C# implementation right?
Your key is different. While crypto-js expects a string, C# expects a byte array. You shouldn't use FromBase64String() but Encoding.UTF8.GetBytes(). As #jps mentioned in the comment
Of course it's different, your JS implementation has a hex encoded
output but in your C# implementation you're base64 encoding the
result.
you should convert the byte-array to a hex-string like so
string signSession = "application_id=3610&auth_key=aDRceQyTXSYEdJU&nonce=6304033672&timestamp=1623098533&user[login]=john#mail.com&user[password]=123456789";
string key = "dBV2PdhYMnruSMb";
//convert the session signature string to a byte array
byte[] signature = Encoding.UTF8.GetBytes(signSession);
var apiKey = Encoding.UTF8.GetBytes(key);
//Generate a HMACSHA1 signature
using (HMACSHA1 hmac = new HMACSHA1(apiKey))
{
byte[] signatureBytes = hmac.ComputeHash(signature);
string hexSignature = BitConverter.ToString(signatureBytes).ToLowerInvariant().Replace("-", "");
Console.WriteLine(hexSignature);
session.Signature = hexSignature;
}

How to decode in JavaScript/Node.js a string of combined UTF16 and normal characters?

I have a huge JSON stringified into a string like this one:
"\\u007B\\u0022name\\u0022\\u003A\\u0022T\\u0065st\\u0022}"
I need to JSON.parse it to use as an object. Do you know any way to decode it?
I tried decodeURIComponent(), unescape(), different variants of .replace( /\\u/g, "\u" ) and I can not get it into the needed form.
You can convert UTF-16 to text using the following function:
function utf16ToText(s) {
return s.replace(/\\u[0-9a-fA-F]{4}/gi, match => {
return String.fromCharCode(parseInt(match.replace(/\\u/g, ""), 16));
});
}
Demo:
const r = utf16ToText("\\u007B\\u0022name\\u0022\\u003A\\u0022T\\u0065st\\u0022\\u007d");
console.log("As text: ", r);
const j = JSON.parse(r);
console.log("As JSON: ", j);
console.log("JSON Prop: ", j.name);
function utf16ToText(s) {
return s.replace(/\\u[0-9a-fA-F]{4}/gi, match => {
return String.fromCharCode(parseInt(match.replace(/\\u/g, ""), 16));
});
}
If your string is valid JSON, then you can use JSON.parse() to process the UTF16 for you. To make what you have valid JSON, you have to add double quotes to each end (inside the actual string) as all strings must be enclosed in double quotes in the JSON format. Here's an example:
let data = "\\u007B\\u0022name\\u0022\\u003A\\u0022T\\u0065st\\u0022\\u007d";
// to make this legal JSON so we can let the JSON parser parse it for us and
// handle the UTF16 for us, we need to put double quotes in the actual string at each end
// Then, it's legal JSON and we can parse it
let str = JSON.parse('"' + data + '"');
console.log(str);
console.log("type is", typeof str);
This gives you a result in string form:
{"name":"Test"}
This result is now legal JSON on its own. If you then wanted to parse that as JSON, could just call JSON.parse() on it again to turn it into an actual Javascript object:
let data = "\\u007B\\u0022name\\u0022\\u003A\\u0022T\\u0065st\\u0022\\u007d";
let str = JSON.parse('"' + data + '"'); // decoded string here
// now take the string and actually parse it into a Javascript object
let obj = JSON.parse(str);
console.log(obj); // Javascript object here
console.log("type is", typeof obj);
This gives you a resulting live Javascript object:
{name:"Test"}
The first call to JSON.parse() just takes your JSON string and decodes it into a Javascript string. Since that Javascript string is now also legal JSON for an object definition, you can call JSON.parse() on it again to turn it into a Javascript object.
Thank you for your input. Because of that, I got the solution:
let a = "\\u007B\\u0022name\\u0022\\u003A\\u0022T\\u0065st\\u0022}" original string
let b = '"' + a + '"' adding " in order to make a valid stringified JSON
let c = JSON.parse(b) that will produce a partially decoded string (partially because some of the \uXXXX characters can stay in the string)
let solution = JSON.parse(c) that will create an object with all the characters decoded
Big thanks to #jfriend00

Generate Base64 MD5 hash of byte array

I have following security encoding implemented in my c# web api:
string testStr = "test";
ASCIIEncoding encoding = new ASCIIEncoding(); //using System.Text;
byte[] byteData = encoding.GetBytes(testStr);
MD5 md5 = MD5.Create(); //using System.Security.Cryptography;
string hash = md5.ComputeHash(byteData);
string md5Base64 = Convert.ToBase64String(hash);
I bind this md5Base64 string in header and compare it in API request. This works fine when I hit the API from C# code. Now I need to use it in javascript, so will need js equivalent of above code.
I have tried following but it is giving different output:
var testStr = 'test';
var byteData = testStr.split ('').map(function (c) { return c.charCodeAt (0); });
var hash = MD5(value.join(','));
var md5Base64 = btoa(hash);
the MD5 function used here is from https://stackoverflow.com/a/33486055/7519287
Please let me know what is wrong here.
The problem with your JavaScript code is that you're doing unnecessary conversions: MD5 already takes a string. Furthermore, more conversions after hashing are required.
If we have the following C# code:
string tmp = "test";
byte[] bTmp = System.Text.Encoding.UTF8.GetBytes(tmp);
byte[] hashed = null;
using (System.Security.Cryptography.MD5CryptoServiceProvider md5 = new System.Security.Cryptography.MD5CryptoServiceProvider())
{
hashed = md5.ComputeHash(bTmp);
}
Console.WriteLine(Convert.ToBase64String(hashed));
Fiddle
then the equivalent JavaScript code is:
var tmp = 'test';
var hashed = hex2a(MD5(tmp)); // md5 src: https://stackoverflow.com/a/33486055/7519287
// src: https://stackoverflow.com/a/3745677/3181933
function hex2a(hexx) {
var hex = hexx.toString();//force conversion
var str = '';
for (var i = 0; i < hex.length; i += 2)
str += String.fromCharCode(parseInt(hex.substr(i, 2), 16));
return str;
}
alert(btoa(hashed));
Fiddle
Because MD5 returns a hex string, you have to convert that to ASCII before you can base64 encode it. I wonder if you need base64 encoding? MD5 is usually represented as a hex string. Perhaps on the C# side, instead of Convert.ToBase64String(hashed), you could use BitConverter.ToString(hashed).Replace("-", "") to get a hex string for the MD5 hash? Then you could simply just use MD5(tmp) in JavaScript.

JSON.parse() returns a string instead of object

I'd hate to open a new question even though many questions have been opened on this same topic, but I'm literally at my ends as to why this isn't working.
I am attempting to create a JSON object with the following code:
var p = JSON.stringify(decodeJSON('{{post.as_json}}'))
var post = JSON.parse(p);
console.log(post); // Debug log to test if code is valid
And the decodeJSON function:
function decodeJSON(json) {
var txt = document.createElement("textarea");
txt.innerHTML = json;
return txt.value.replace(/u'/g, "'");
}
console.log(post) returns the following JSON string:
{'content': 'kj fasf', 'uid': '4eL1BQ__', 'created': '07/09/2017', 'replies': [], 'tags': ['python'], 'by': {'username': 'Dorian', 'img_url': '/static/imgs/user_Dorian/beaut.jpg'}, 'likes': 0}
After scanning through the string I am pretty sure that the JSON is valid and there are no syntax errors. However, when running JSON.parse(p) Instead of receiving an object, I get a string back. What could be the cause?
That's because decodeJSON returns a string, and JSON.stringify turns that string in another string.
In the other hand, you used JSON.strigify() method on a string. You should stringify an object, not string.
JSON.stringify() turns a javascript object to json text and stores it
in a string.
When you use JSON.parse you obtain the string returned by decodedJSON function, not object.
Solution:
var p = JSON.stringify('{{post.as_json}}');
var post = JSON.parse(p);
console.log(post);
It gives me Uncaught SyntaxError: Unexpected token ' in JSON at
position 1
The solution is to modify your decodeJSON method.
function decodeJSON(json) {
var txt = document.createElement("textarea");
txt.innerHTML = json;
return txt.value.replace(/u'/g, '\"');
}
var p = decodeJSON('{{post.as_json}}');
var post = JSON.parse(p);
console.log(post);
The issue in your code is that you are performing JSON.stringify on a string itself. So on parsing the result of this string will be a string. In effect, you have stringified twice and parsed once. If you parse it once more you will get a JSON. But for solution avoid the stringification twice.
Replace in your code.
var p = decodeJSON('{{post.as_json}}');
That will work

Decompressing string (from gzcompress) returns wrong result when special chars are involved

I'm trying to write a front end application in js and I am getting my data (Iā¤U\nšŸ˜˜šŸ˜˜šŸ˜˜) from a webserver.
jsFiddle https://jsfiddle.net/czmovg26/1/
Webserver:
<?php
print($compressed = base64_encode(gzcompress('I\u2764U\n\uD83D\uDE18\uD83D\uDE18\uD83D\uDE18', 6)));
?>
Frontend:
var b64Data = "eJzzjCk1MjczCY3Jiyl1sTB2AZKuhha42ABGUQ2i"; // === Iā¤U\nšŸ˜˜šŸ˜˜šŸ˜˜
// Decode base64 (convert ascii to binary)
var strData = atob(b64Data);
// Convert binary string to character-number array
var charData = strData.split('').map(function (x) {
return x.charCodeAt(0);
});
// Turn number array into byte-array
var binData = new Uint8Array(charData);
// Pako magic
var data = pako.inflate(binData);
// Convert gunzipped byteArray back to ascii string:
var decoded = String.fromCharCode.apply(null, new Uint8Array(data));
var r = /\\u([\d\w]{4})/gi;
decoded = decoded.replace(r, function(match, grp) {
return String.fromCharCode(parseInt(grp, 16));
});
decoded = unescape(decoded);
Now, the string looks the same when you print it in the console, but
console.log(decoded == "Iā¤U\nšŸ˜˜šŸ˜˜šŸ˜˜");
resturns false, and things like
var val = decoded.replace(RegExp("\n","g"), "<br>");
do not work.
The decompression must be the problem, as it works fine with a normal string, but I don't understand, what's wrong with the decompression.
In JavaScript a string literal with \n in it denotes a new line, if you were to log such a string to the console you would see it split along multiple lines.
If you take a look at the log of the decoded string you'd notice its on a single line.
This means your original string did not have a new line in it.
From your php you can see that very clearly. In php the escape slash only escapes the single quote in a single quoted php string, so for \n to represent a newline it has to be within a double quoted string.
<?php
print($compressed = base64_encode(gzcompress("I\u2764U\n\uD83D\uDE18\uD83D\uDE18\uD83D\uDE18", 6)));

Categories

Resources