fluxb0x
fluxb0x

Reputation: 83

How to encrypt data in browser with JavaScript and decrypt on server side with Node.js

I'm trying to encrypt a message using AES256 on the browser, send it to the server, and then decrypt it but I keep getting this error server-side :

error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt

I tried for hours to find a solution but I don't see where is the issue. I'm using crypto-js for client-side and the standard library for Node.js crypto

This is the code sample that I'm using on client-side.

import * as CryptoJS from 'crypto-js';

const secret = 'example';
const passphrase = 'secret-passphrase'

const encrypted = CryptoJS.AES.encrypt(secret, passphrase);
const encrypted64 = CryptoJS.enc.Base64.stringify(encrypted.ciphertext);

// make a request to a Node.js API with the password encrypted

This is the code sample that I'm using on server-side.

const crypto = require('crypto');

const secret = req.body.secret;

const passphrase = 'secret-passphrase'
const decipher = crypto.createDecipher('aes256', passphrase);

let decrypted = decipher.update(secret, 'base64', 'utf8');
decrypted += decipher.final('utf8');

Any idea?

Thanks.

Upvotes: 1

Views: 5885

Answers (2)

Djesu
Djesu

Reputation: 117

Using HTTPS will encrypt the payload during the transfer and have it decrypted at the server. HTTPS uses RSA to encrypt the keys used in the encryption of the message.
RSA uses 1024 bit key value which is difficult to crack. The hacker has to factor large numbers into their original prime values to get the keys which makes its almost impossible to crack.

It is generally advisable to use HTTPS in your transmissions.

Upvotes: 2

RKalra
RKalra

Reputation: 569

The error generally occurs when you use the wrong key.

You are using different packages to begin with. crypto-js will take your passphrase, create a key and encrypt cleartext that you have in secret. crypto will do the same when you create Decipher, but then there's the issue of padding. In short, key is not same for crypto when decrypting.

Use a 32 bytes key like abcabcabc1abcabcabc1abcabcabc132

Go for client-side encryption like:

var ciphertext= C.AES.encrypt(secret, C.enc.Hex.parse(passphrase), { mode: C.mode.ECB, padding: C.pad.NoPadding }).ciphertext.toString();

And on your server side code go for following (after passing the same passphrase to decipher):

let decrypted = decipher.update(ciphertext, 'hex', 'utf8');

Give it a try. It should work. It will be easier if you use crypto-js on both client and server.

Hope it helps!

Upvotes: 1

Related Questions