How to get Java DigestUtils.md5() output from Javascript? - javascript

Java code that uses
Apache Commons library to generate signature:
byte[] md5 = DigestUtils.md5("test");
String signature = Base64.encodeBase64String(md5);
System.out.println(signature);
// CY9rzUYh03PK3k6DJie09g==
Javascript code I am trying to write to get the same output:
const md5 = CryptoJS.MD5("test");
const signature = btoa(md5);
console.log(signature);
// MDk4ZjZiY2Q0NjIxZDM3M2NhZGU0ZTgzMjYyN2I0ZjY=
I know how to get the same output if I change the Java code like this:
String md5 = DigestUtils.md5Hex("test");
String signature = Base64.encodeBase64String(md5.getBytes(StandardCharsets.UTF_8));
System.out.println(signature);
// MDk4ZjZiY2Q0NjIxZDM3M2NhZGU0ZTgzMjYyN2I0ZjY=
But unfortunately I am not allowed to modify Java code, so how can I modify Javascript code instead, to get the same output as Java code?

I think I found the solution by myself:
const md5 = CryptoJS.MD5("test");
const signature = md5.toString(CryptoJS.enc.Base64);
console.log(signature);
// CY9rzUYh03PK3k6DJie09g==

Related

Convert encryption function from Javascript to Python

I'm trying to convert this code from Javascript to Python3:
import crypto from 'crypto';
const secretKey = 'NgTriSCalcUltAbLoGResOnOuSeAKeSTraLryOuR'
function verifySignature(rawBody) {
const calculatedSignature = crypto
.createHmac('sha256', secretKey)
.update(rawBody, 'utf8')
.digest('base64');
return calculatedSignature;
}
console.log(verifySignature('a'));
With that code I get this output: vC8XBte0duRLElGZ4jCsplsbXnVTwBW4BJsUV1qgZbo=
So I'm trying to convert the same function to Python using this code:
UPDATED
import hmac
import hashlib
message = "a"
key= "NgTriSCalcUltAbLoGResOnOuSeAKeSTraLryOuR"
hmac1 = hmac.new(key=key.encode(), msg=message.encode(), digestmod=hashlib.sha256)
message_digest1 = hmac1.hexdigest()
print(message_digest1)
But I get this error: AttributeError: 'hash' object has no attribute 'digest_size'
Can someone tell me what I am missing to achieve the same output in Python?
Thanks you! :)
You're not getting base64 from the digest() on your return statement. In your javascript code it was also encoded in UTF-8 which should be specified below. The key was also not supplied in your python code.
This code snippet I just tested should generate the same result as your javascript code:
def newhashab(msg, key):
digest = hmac.new(key.encode('UTF-8'), msg.encode('UTF-8'), hashlib.sha256)
return base64.b64encode(digest.digest()).decode('UTF-8')
print(newhashab("a", 'NgTriSCalcUltAbLoGResOnOuSeAKeSTraLryOuR'))
It should return:
'vC8XBte0duRLElGZ4jCsplsbXnVTwBW4BJsUV1qgZbo='

Equivalent JavaScript code to generate SHA256 hash

I have this code in Java that generates a SHA256 hash:
Hashing.sha256().hashString(value,Charsets.UTF_16LE).toString()
I'm trying to do the same on JavaScript/Node, that having the same value returns the same result.
I tried usind crypto-js but without success (it returns a hash string but different from the one generated with the Java code).
I tried this, for example:
import * as sha256 from 'crypto-js/sha256';
import * as encutf16 from 'crypto-js/enc-utf16';
...
let utf16le = encutf16.parse(key);
let utf16Sha256 = sha256(utf16le);
let utf16Sha256String = utf16Sha256.toString();
Can you try something like this :-
const CryptoJS = require('crypto-js');
let utf16le = CryptoJS.enc.Utf16LE.parse(word);
let utf16Sha256 = CryptoJS.SHA256(utf16le);
return utf16Sha256.toString(CryptoJS.enc.Hex);
Or else if you can give a sample of whats the input and expected output corresponding to JAVA code it will be easier

Javascript. How To Efficiently Store Secp256k1 Private Key for ECIES Scheme

I've been having a really hard time figuring out how to store a Secp256k1 privateKey from multiple libraries (currently on this one for ECIES encryption: https://npm.io/package/#toruslabs/eccrypto).
I have tried encoding and decoding with base64, many implementations of functions that copy array buffer for input encoded string to localStoarge and corresponding output Uint8Array from localStorage, I tried it with IndexedDB, JSON.stringify and parse do not work with binary data, and so many more variations.
When I go through the array buffer elements individually to copy it into a new Uint8Array, I get a similar private key, but with two missing key/field's (parent and offset) which I believe is why every library I have tried so far returns something a long the lines of "bad private key" when I try generating the public key from them.
I am exhausted and I would like some professional insight for my lack of skill in this particular subject. So how can I store (in any way as long as it's client/local) a Secp256k1 private key in a way that if I call it from that persistent client sided data base, they can be used to generate the public keys?
Apparently, the library that uses the private/public key (in this case being #toruslabs/eccrypto) requires a buffer parameter for the keys.
A simple solution would be to make the NodeJS Buffer available in the browser, through browserify. You will only need to include the NodeJS Buffer class to the window object when creating the browserify file, as shown:
const eccrypto = require('./index');
window.eccrypto = eccrypto;
window.Buffer = Buffer;
Then, generate the bundle file using browserify: browserify main.js -o bundle.js
After this, you will be able to use the Buffer class in your browser, which will make loading the private/public key possible. Sample code here:
<script src="bundle.js"></script>
<script>
const eccrypto = window.eccrypto;
const privateKey = eccrypto.generatePrivate();
const publicKey = eccrypto.getPublic(privateKey);
// hex string output of private key
const hexPrivateKey = privateKey.toString('hex')
console.log(hexPrivateKey); // we can do this as privateKey is a Buffer
// load private key again
const newPrivateKey = Buffer.from(hexPrivateKey, 'hex');
const enc = new TextEncoder();
// code referenced from #toruslabs/eccrypto README
// Encrypting the message.
eccrypto.encrypt(publicKey, enc.encode("my testing msg")).then(function (encrypted) {
// Decrypting the message.
eccrypto.decrypt(newPrivateKey, encrypted).then(function (plaintext) {
console.log("Message:", plaintext.toString());
});
});
</script>
This should be sufficient to store the hex string of the private key in the localStorage or any client-side database/storage that you will be using.

Mechanisms for hashing a file in JavaScript

I am relatively new to JavaScript and I want to get the hash of a file, and would like to better understand the mechanism and code behind the process.
So, what I need: An MD5 or SHA-256 hash of an uploaded file to my website.
My understanding of how this works: A file is uploaded via an HTML input tag of type 'file', after which it is converted to a binary string, which is consequently hashed.
What I have so far: I have managed to get the hash of an input of type 'text', and also, somehow, the hash of an uploaded file, although the hash did not match with websites I looked at online, so I'm guessing it hashed some other details of the file, instead of the binary string.
Question 1: Am I correct in my understanding of how a file is hashed? Meaning, is it the binary string that gets hashed?
Question 2: What should my code look like to upload a file, hash it, and display the output?
Thank you in advance.
Basically yes, that's how it works.
But, to generate such hash, you don't need to do the conversion to string yourself. Instead, let the SubtleCrypto API handle it itself, and just pass an ArrayBuffer of your file.
async function getHash(blob, algo = "SHA-256") {
// convert your Blob to an ArrayBuffer
// could also use a FileRedaer for this for browsers that don't support Response API
const buf = await new Response(blob).arrayBuffer();
const hash = await crypto.subtle.digest(algo, buf);
let result = '';
const view = new DataView(hash);
for (let i = 0; i < hash.byteLength; i += 4) {
result += view.getUint32(i).toString(16).padStart(2, '0');
}
return result;
}
inp.onchange = e => {
getHash(inp.files[0]).then(console.log);
};
<input id="inp" type="file">

What's the encoding should I use to "gzuncompress()" in node.js?

I'm converting my code from PHP to node.js, and I need to convert a part of my code where there's the gzuncompress() function.
For that I'm using zlib.inflateSync. But I don't know which encoding I should use to create the buffer and so to have the same result of php
Here's what I do with php to decompress a string:
gzuncompress(substr($this->raw, 8))
and here's what I've tried in node.js
zlib.inflateSync(new Buffer(this.raw.substr(8), "encoding"))
So what encoding should I use to make zlib.inflateSync returns the same data as gzuncompress ?
I am not sure about what would be exact encoding here however this repo has some PHP translations for node.js (https://github.com/gamalielmendez/node-fpdf/blob/master/src/PHP_CoreFunctions.js). According to this repo, the following could work:
const gzuncompress = (data) => {
const chunk = (!Buffer.isBuffer(data)) ? Buffer.from(data, 'binary') : data
const Z1 = zlib.inflateSync(chunk)
return Z1.toString('binary')//'ascii'
}

Categories