Decrypt the crypto data - javascript

I am trying to encrypt and decrypt values using node inbuild module crypto. I have followed this tutorial to encrypt the data. They haven't to gave any sample code to decrypt. When I try to use other tutorial code to decrypt the data. It not working out. Please help me out,
Code
const crypto = require('crypto');
// Difining algorithm
const algorithm = 'aes-256-cbc';
// Defining key
const key = crypto.randomBytes(32);
// Defining iv
const iv = crypto.randomBytes(16);
// An encrypt function
function encrypt(text) {
// Creating Cipheriv with its parameter
let cipher = crypto.createCipheriv(
'aes-256-cbc', Buffer.from(key), iv);
// Updating text
let encrypted = cipher.update(text);
// Using concatenation
encrypted = Buffer.concat([encrypted, cipher.final()]);
// Returning iv and encrypted data
return encrypted.toString('hex');
}
var op = encrypt("Hi Hello"); //c9103b8439f8f1412e7c98cef5fa09a1

Since you havent provided the code for decryption, Cant help you what is actually wrong you doing, apart from that you can do this to get decrypted code:
const crypto = require('crypto')
// Defining key
const key = crypto.randomBytes(32)
// Defining iv
const iv = crypto.randomBytes(16)
// An encrypt function
function encrypt(text) {
// Creating Cipheriv with its parameter
const cipher = crypto.createCipheriv('aes-256-cbc', Buffer.from(key), iv)
// Updating text
let encrypted = cipher.update(text)
// Using concatenation
encrypted = Buffer.concat([encrypted, cipher.final()])
// Returning iv and encrypted data
return encrypted.toString('hex')
}
var op = encrypt('Hi Hello')
console.log(op)
function decrypt(data) {
// Creating Decipheriv with its parameter
const decipher = crypto.createDecipheriv('aes-256-cbc', Buffer.from(key), iv)
// Updating text
const decryptedText = decipher.update(data, 'hex', 'utf8')
const finalText = decryptedText + decipher.final('utf8')
return finalText
}
var decrptedData = decrypt(op)
console.log(decrptedData)

Related

Fetching Encrypted Buffer Data to use as ArrayBuffer for client-side decryption

I am attempting to fetch encrypted raw buffer data (AES-256) from Arweave, pass to a decrypt function and use this to display an image. I am trying to fetch and decrypt the ArrayBuffer on the front end (in my React app).
First, I am encrypting the Buffer data in NodeJS and storing the file. Here is the code for it:
/**********************
** Runs in NodeJS **
**********************/
const encrypt = (dataBuffer, key) => {
// Create an initialization vector
const iv = crypto.randomBytes(IV_LENGTH);
// Create cipherKey
const cipherKey = Buffer.from(key);
// Create cipher
const cipher = crypto.createCipheriv(ALGORITHM, cipherKey, iv);
const encryptedBuffer = Buffer.concat([
cipher.update(dataBuffer),
cipher.final(),
]);
const authTag = cipher.getAuthTag();
let bufferLength = Buffer.alloc(1);
bufferLength.writeUInt8(iv.length, 0);
return Buffer.concat([bufferLength, iv, authTag, encryptedBuffer]);
};
const encryptedData = encrypt(data, key)
fs.writeFile("encrypted_data.enc", encryptedData, (err) => {
if(err){
return console.log(err)
}
});
Next, I try to fetch and decrypt on the front-end. What I have so far returns an ArrayBuffer from the response. I try to pass this ArrayBuffer to the decrypt function. Here is the code:
/***********************
** Runs in React **
***********************/
import crypto from "crypto"
const getData = async (key) => {
const result = await (await fetch('https://arweave.net/u_RwmA8gP0DIEeTBo3pOQTJ20LH2UEtT6LWjpLidOx0/encrypted_data.enc')).arrayBuffer()
const decryptedBuffer = decrypt(result, key)
console.log(decryptedBuffer)
}
// Here is the decrypt function I am passing the ArrayBuffer to:
export const decrypt = (dataBuffer, key) => {
// Create cipherKey
const cipherKey = Buffer.from(key);
// Get iv and its size
const ivSize = dataBuffer.readUInt8(0);
const iv = dataBuffer.slice(1, ivSize + 1);
// Get authTag - is default 16 bytes in AES-GCM
const authTag = dataBuffer.slice(ivSize + 1, ivSize + 17);
// Create decipher
const decipher = crypto.createDecipheriv("aes-256-gcm", cipherKey, iv);
decipher.setAuthTag(authTag);
return Buffer.concat([
decipher.update(dataBuffer.slice(ivSize + 17)),
decipher.final(),
]);
};
When I pass the ArrayBuffer data to the decrypt function, I get this error:
Unhandled Rejection (TypeError): First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.
You're omitting a lot of details that would help the community understand how you're encrypting the image, how you're retrieving it, and how you're decrypting it. Here's a full example of fetching an image, encrypting it, decrypting it, and displaying it in the browser. This runs in Chrome v96 and Firefox v95.
(async () => {
const encryptionAlgoName = 'AES-GCM'
const encryptionAlgo = {
name: encryptionAlgoName,
iv: window.crypto.getRandomValues(new Uint8Array(12)) // 96-bit
}
// create a 256-bit AES encryption key
const encryptionKey = await crypto.subtle.importKey(
'raw',
new Uint32Array([1,2,3,4,5,6,7,8]),
{ name: encryptionAlgoName },
true,
["encrypt", "decrypt"],
)
// fetch a JPEG image
const imgBufferOrig = await (await fetch('https://fetch-progress.anthum.com/images/sunrise-baseline.jpg')).arrayBuffer()
// encrypt the image
const imgBufferEncrypted = await crypto.subtle.encrypt(
encryptionAlgo,
encryptionKey,
imgBufferOrig
)
// decrypt recently-encrypted image
const imgBufferDecrypted = await crypto.subtle.decrypt(
encryptionAlgo,
encryptionKey,
imgBufferEncrypted
)
// display unencrypted image
const img = document.createElement('img')
img.style.maxWidth = '100%'
img.src = URL.createObjectURL(
new Blob([ imgBufferDecrypted ])
)
document.body.append(img)
})()

Decrypt function can't read content hash throws : TypeError [ERR_INVALID_ARG_TYPE]:

When I first tested it both the encrypt and decrypt using the aes-256-ctr algorithm worked fine but after I posted it to IPFS and returned it it gave me the following error.
TypeError [ERR_INVALID_ARG_TYPE]: The first argument must be of type string or an instance of Buffer, ArrayBuffer, or Array or an Array-like Object. Received undefined
It all looks up to par for me.
Here is the encryption.js file.
const crypto = require('crypto');
const algorithm = 'aes-256-ctr';
const secretKey = 'vOH6sdmpNWjRRIqCc7rdxs01lwHzfr33';
const iv = crypto.randomBytes(16);
//const file = fs.readFileSync("test.txt");
//console.log(secretKey.length);
const encrypt = (text) => {
const cipher = crypto.createCipheriv(algorithm, secretKey, iv);
const encrypted = Buffer.concat([cipher.update(text), cipher.final()]);
return {
iv: iv.toString('hex'),
content: encrypted.toString('hex')
};
};
const decrypt = (hash) => {
const decipher = crypto.createDecipheriv(algorithm, secretKey, Buffer.from(hash.iv, 'hex'));
const decrypted = Buffer.concat([decipher.update(Buffer.from(hash.content, 'hex')),
decipher.final()]);
return decrypted.toString();
};
It seems to work for me -- but only if you pass the entire object returned by encrypt into decrypt. If you just pass in the hash without the iv, you get that error.

Why is my decipher.update returning a function and not the deciphered text? NodeJS

I am using the inbuilt crypto module, and been frustrated for many hours trying to figure out why decipher.update returns a function and not the deciphered text itself.
code:
const file = path.join(__dirname, '../secret.txt');
const fileIV = path.join(__dirname, '../iv.txt');
const at = path.join(__dirname, '../at.txt')
var secret = fs.readFileSync(file, 'utf-8');
const algorithm = 'aes-256-gcm';
var text = 'default'
var encrypted = secret;
const iv = crypto.randomBytes(16);
encrypt(plainText, key, iv) {
const cipher = crypto.createCipheriv(algorithm, key, iv);
return { encrypted: Buffer.concat([cipher.update(plainText), cipher.final()]), authTag: cipher.getAuthTag() }
}
decrypt(encrypted, key, iv, authTag) {
const decipher = crypto.createDecipheriv(algorithm, key, iv).setAuthTag(authTag);
console.log('this worked decrypt');
return Buffer.concat([decipher.update(encrypted), decipher.final()]);
}
SignUp(pass)
{
console.log(pass);
var pair = ec.genKeyPair();
text = pair.getPrivate.toString('hex');
const key = crypto.scryptSync(pass, 'baethrowssalt', 32);
console.log(`The key is:${key}`);
const {encrypted, authTag} = this.encrypt(text, key, iv);
console.log('encrypted: ',encrypted.toString('hex'));
const decrypted = this.decrypt(encrypted, key, iv, authTag);
console.log('Decrypted:', decrypted.toString('utf-8'));
return console.log(`Close and reopen your app to integrate your wallet securely`);
}
in console it prints this when I print out the decrypted result of the private key I initially tried encrypting with scrypt:
Decrypted: function getPrivate(enc) {
if (enc === 'hex')
return this.priv.toString(16, 2);
else
return this.priv;
}
why is
decrypt(encrypted, key, iv, authTag) {
const decipher = crypto.createDecipheriv(algorithm, key, iv).setAuthTag(authTag);
console.log('this worked decrypt');
return Buffer.concat([decipher.update(encrypted), decipher.final()]);
}
not giving me the text in its deciphered form? Additionally, how can I obtain it since I am clearly doing something wrong. Any help would really be appreciated.
The result of the decryption is exactly the same as the plaintext you encrypted!
You can easily verify this by outputting the plaintext, i.e. the contents of text, in SignUp() in the console before encrypting it:
var text = pair.getPrivate.toString('hex');
console.log('Initial plaintext:', text); // Initial plaintext: function getPrivate(enc) {...
The reason for the unexpected content of text is that you simply forgot the pair of parentheses after getPrivate, it should be:
var text = pair.getPrivate().toString('hex');
console.log('Initial plaintext:', text); // Initial plaintext: <the hex encoded private key>
Then the decryption provides the expected result.
It is probably because "decrypted.toString('utf-8')" is not executing the function but turning it into a string to show in the console...
I believe you have to do something like:
let decryptedResult = decrypted.toString('utf-8'); console.log('Decrypted:', decryptedResult.toString('utf-8'));
or but not sure
console.log('Decrypted:', (decrypted).toString('utf-8'));

How to use node-js crypto in javascript?

I need following encryption decryption, but in java script for client-side.
This code is written in Node-JS and using crypto library, i couldn't find same solution for java script for client side run.
const crypto = require('crypto');
const decrypt = (textBase64, keyBase64, ivBase64) => {
const algorithm = 'aes-256-cbc';
const ivBuffer = Buffer.from(ivBase64, 'base64');
const keyBuffer = Buffer.from(keyBase64, 'base64');
const decipher = crypto.createDecipheriv(algorithm, keyBuffer, ivBuffer);
decipher.setAutoPadding(false);
let decrypted = decipher.update(textBase64, 'base64', 'utf8');
decrypted += decipher.final('utf8');
return decrypted;
}
const encryptedMessage = '';
const key = 'cGFzc3dvcmQxMjM0NTY3ODk=';
const iv = Buffer.from(encryptedMessage, 'base64').slice(0, 16);
// the message comes from the bytes AFTER the IV - this is what you should decrypt
const message = Buffer.from(encryptedMessage, 'base64').slice(16);
const result = decrypt(message, key, iv);
console.log(result);
//console.log(Buffer.from(encryptedMessage, 'base64').slice(0, 16))
First I would say it is not recommended to decrypt on the client side as the key is visible. but you know what you do.
this library is pure JS and should be working in a browser without any pain : ricmoo/aes-js

How to decrypt message with CryptoJS AES? I have a working node crypto example

I am able decrypt AES encrypted message using Node's crypto library as follow
const crypto = require('crypto');
const encryptedData = 'b6ab428efbcb93c2f483178114ac0608530e54428f1378c6d3be108531b730d1888e562044cd3acb8844a04d9d7602d83b96f0a758248ffd07cd9c530b76c91c';
const decryptResponse2 = (data) => {
const key = 'F5:A4:F4:AB:BF:68:CF:86:51:B4:AA';
const iv = Buffer.from(data.substring(0, 32), 'hex');
const payload = data.substring(32);
const decipher = crypto.createDecipheriv('aes-256-cbc', key, iv).setAutoPadding(false);
const decipherFinal = decipher.update(payload, 'hex', 'utf8') + decipher.final('utf8');
console.log(decipherFinal);
};
decryptResponse2(encryptedData);
I create a script using crypto-js library as that is available to be used in browser. The code I tried is as follow:
const crypto = require('crypto-js');
const encryptedData = 'b6ab428efbcb93c2f483178114ac0608530e54428f1378c6d3be108531b730d1888e562044cd3acb8844a04d9d7602d83b96f0a758248ffd07cd9c530b76c91c';
const decryptResponse = (data) => {
const key = 'F5:A4:F4:AB:BF:68:CF:86:51:B4:AA';
const iv = Buffer.from(data.substring(0, 32), 'hex');
const payload = data.substring(32);
let decryptedData = crypto.AES.decrypt(
payload,
key,
{
iv: iv,
mode: crypto.mode.CBC,
padding: crypto.pad.NoPadding
});
console.log(decryptedData.toString());
}
decryptResponse(encryptedData);
However, not only is it generating wrong decrypted data, the decrypted message is not even consistent. I don't know what I am doing wrong as I do not know much about encryption and decryption.
Any help will be apriciated.
Thanks to #GrafiCode pointing me to the right place, I was able to solve it using format property of config object.
Following is the code:
const crypto = require('crypto-js');
const encryptedData = 'b6ab428efbcb93c2f483178114ac0608530e54428f1378c6d3be108531b730d1888e562044cd3acb8844a04d9d7602d83b96f0a758248ffd07cd9c530b76c91c';
const decryptResponse = (data) => {
const key = crypto.enc.Utf8.parse('F5:A4:F4:AB:BF:68:CF:86:51:B4:AA');
const iv = crypto.enc.Hex.parse(data.substring(0, 32));
const payload = data.substring(32);
let decryptedData = crypto.AES.decrypt(
payload,
key,
{
iv: iv,
mode: crypto.mode.CBC,
// padding: crypto.pad.NoPadding,
format: crypto.format.Hex
});
console.log(crypto.enc.Utf8.stringify(decryptedData));
}
decryptResponse(encryptedData);
I commented out the padding: crypto.pad.NoPadding as there were non-printable characters at the end of the decryptedData when it was enabled.

Categories