How to remove "unneeded" bytes of a ciphertext? - javascript

I am using node-js and crypto library to encrypt/decrypt my strings with AES-128 encryption. But I have a problem, that's the pads to make a string multiple of 16 bytes. How can I remove those bytes? Because I can't use decrypted_string == "actual string" (because of the unneeded bytes at end of the string) in javascript. Here are the functions which I use to encrypt / decrypt strings in javascript:
const crypto = require("crypto");
function encrypt(str, key) {
let input = Buffer.from(str, "utf8");
let token = Buffer.from(key);
cipher = crypto.createCipheriv("aes-128-ecb", token, '');
result = cipher.update(input).toString("base64");
result += cipher.final().toString("base64");
return result;
}
function decrypt(str, key) {
let input = Buffer.from(str, "base64");
let token = Buffer.from(key);
decipher = crypto.createDecipheriv("aes-128-ecb", token, '');
decipher.setAutoPadding(false);
result = decipher.update(input).toString("utf8");
result += decipher.final().toString("utf8");
return result;
}

Related

Conversion from buffer to string gives different results in c# and Nodejs

I'm trying to convert this function from C# to node but I'm getting different results when I try to convert a buffer to a string.
string str = "34924979";
System.Security.Cryptography.SHA512 sha = new System.Security.Cryptography.SHA512Managed();
byte[] ba = System.Text.Encoding.ASCII.GetBytes(str);
byte[] data= sha.ComputeHash(ba);
Console.WriteLine(System.Text.Encoding.ASCII.GetString(data));
>> `?????gV)????∟?Z?s??v$We-??N?"?w????0??\i♠G???
that's what i'm trying to do.
const crypto = require('crypto')
const str = '34924979';
const sha = crypto.createHash('sha512').update(str).digest('utf8');
const hash = sha.toString('utf-8').replace(/\uFFFD/g, '?');
console.log(hash);
>> `????gV)????∟?Z?v$We-??N?"?w????0?\i♠Gߕ?
You're using different encodings in C# and JS.
Try changing the JS code to the following:
const sha = crypto.createHash('sha512').update(str).digest('ascii');
const hash = sha.toString('ascii');

How to convert MD5 with BigInt MD5 Hash to String format in NodeJs with equivalent code from Java

I have the following code in Java for MD5 hash. I want to convert into in equivalent NodeJs with Typescript.
Code in Java
String secretKey = "MyID~Denmark";
final MessageDigest md = MessageDigest.getInstance("MD5") final byte[] messageDigest = md.digest(secretKey.getBytes());
final BigInteger number = new BigInteger(messageDigest);
String value = String.format("%032x", number);
System.out.println("Value: "+value);
I have also tried in the following Typescript code, the results from Java and NodeJs are not equal.
public checkMd51(): void {
const country: string = "Denmark";
const projectId: string = "MyID";
const secretKey: string = projectId + "~" + country;
// const key: string = crypto.createHash("md5").update(String(secretKey)).digest();
const md5 = crypto.createHash('md5').update(secretKey).digest('hex');
const bigInt = BigInt(`0x${md5.substring(0, 32)}`);
// const bigInt = BigInt(`0x${md5}`);
// const val1 = util.format('%s:%s:%s', bigInt);
console.log("MD5 value: ", val1.toString());
}
Please help me.
Here you go. The following code is the equivalent of what you have written for MD5 digest in java.
const country: string = "Denmark";
const projectId: string = "MyID";
const secretKey: string = projectId + "~" + country;
const md5 = crypto.createHash('md5').update(secretKey).digest('hex');
console.log("MD5: ", md5);
Run both java program and the above code with Typescript and NodeJs and you can verify that both are equal.

How to SHA-256 hash text in a chrome extension with SubtleCrypto

I am hashing a text field with Subtle Crypto and getting an [object ArrayBuffer].
The relevant code is here:
async function asyncCall() {
var enc = new TextEncoder(); // always utf-8
var enc2 = new TextDecoder(); // always utf-8
var digest3 = enc.encode(localStorage.getItem("Item 1"));
const digest2 = await crypto.subtle.digest("SHA-256", (digest3));
localStorage.setItem("Item Hashed", (digest2));
field2.value = localStorage.getItem("Item Hashed");
};
When I hash any text ("Item 1" is localStorage text that is defined with a text field) with this, I get [object ArrayBuffer] as the result. Why am I not getting something that looks like a SHA256 hash?
Convert ArrayBuffer to a Hex string:
const hashArray = Array.from(new Uint8Array(digest2)); // convert buffer to byte array
const hashHex = hashArray.map(b => b.toString(16).padStart(2, '0')).join(''); // convert bytes to hex string
https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/digest#converting_a_digest_to_a_hex_string

Reassemble crypto hmac code in C#

I am trying to reassemble code in C# from JavaScript, Node js code.
I wrote fully working example in Node just to find out if the code is working correctly but now i am having problems with finding equivalent functions in C#.
JavaScript code using Node.js.
var crypto = require('crypto');
var timestamp = Date.now() / 1000;
var what = timestamp + "hello";
var secret = "SGVsbG8gV29ybGQ=";
var key = Buffer(secret, 'base64');
var hmac = crypto.createHmac('sha256', key);
hmac.update(what);
var t = hmac.digest('base64');
console.log(t);
I am only in need of knowing how to reassemble those functions:
var key = Buffer(secret, 'base64');
var hmac = crypto.createHmac('sha256', key);
hmac.update(what);
Here's a c# example. It includes a function. You would pass your timestamp info as the string I assume, but it can be done with any string.
https://dotnetfiddle.net/eAZGfE
public static string HashString(string StringToHash, string HachKey)
{
System.Text.UTF8Encoding myEncoder = new System.Text.UTF8Encoding();
byte[] Key = myEncoder.GetBytes(HachKey);
byte[] Text = myEncoder.GetBytes(StringToHash);
System.Security.Cryptography.HMACSHA1 myHMACSHA1 = new System.Security.Cryptography.HMACSHA1(Key);
byte[] HashCode = myHMACSHA1.ComputeHash(Text);
string hash = BitConverter.ToString(HashCode).Replace("-", "");
return hash.ToLower();
}

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.

Categories

Resources