ReadableStream is not defined - javascript

I want to encrypt some blobs in azure and I am using Streams API.
I am reading from a blob storage from a container and trying to push the blobs encrypted in other container.
Despite the fact that the instance of new ReadableStream() is recognized, I get logged the error "ReadableStream is not defined"
Any help on this, is more than welcome!
The code
const { BlobServiceClient } = require('#azure/storage-blob');
const openpgp = require('openpgp');
const {privateKey, publicKey} = require('./keys')
async function main() {
const AZURE_STORAGE_CONNECTION_STRING = process.env.AZURE_STORAGE_CONNECTION_STRING;
const blobServiceClient = BlobServiceClient.fromConnectionString(AZURE_STORAGE_CONNECTION_STRING);
const containerClient = blobServiceClient.getContainerClient("uploadebs");
const containerEncryptedFiles = blobServiceClient.getContainerClient("encrypted-dide");
await containerEncryptedFiles.createIfNotExists("encrypted-dide")
// RSA keys
// console.log(`private key => ${privateKey}`)
// console.log(`public key => ${publicKey}`)
// .then((keyPair) => {console.log(`${JSON.stringify(keyPair)}` )}).catch((error) => console.log(`error in generating the keys: ${error}`));
for await (const blob of containerClient.listBlobsFlat()) {
if (blob.name.match('^DIDE*')) {
const blockBlobClient = containerClient.getBlockBlobClient(blob.name);
const encryptedblockBlobClient = containerEncryptedFiles.getBlockBlobClient(blob.name)
const downloadBlockBlobResponse = await blockBlobClient.download(0);
let blobData = await streamToString(downloadBlockBlobResponse.readableStreamBody)
const readableStream = new ReadableStream({
start(controller) {
controller.enqueue(blobData);
controller.close();
}
});
const encrypted = await openpgp.encrypt({
message: await openpgp.createMessage({ text: readableStream }), // input as Message object
publicKeys: publicKey, // for encryption
privateKeys: privateKey // for signing (optional)
});
console.log(encrypted);
await encryptedblockBlobClient.upload(encrypted, encrypted.length)// the blob should be already crypted
}
}
}
async function streamToString(readableStream) {
return new Promise((resolve, reject) => {
const chunks = [];
readableStream.on("data", (data) => {
chunks.push(data.toString());
});
readableStream.on("end", () => {
resolve(chunks.join(""));
});
readableStream.on("error", reject);
});
}
main().then(() => console.log('Done')).catch((ex) => console.log(ex.message));
package.json
{ .
.
.
"dependencies": {
"#azure/storage-blob": "^12.0.0",
"#types/dotenv": "^4.0.3",
"dotenv": "^6.0.0",
"node": "^16.4.0",
"openpgp": "^5.0.0-3"
}

Related

How to set up a SlashCommand with custom options for discord

I've been at this for 4h now... I'm making a discord bot that should take a user's input and define the word using an API call. I have an index.js that should call my urban.js file and define a word a user inputs. For example, if a user inputs "/urban cow," the bot should put the definition of a cow. However, right now it cannot read the option after "/urban" no matter what I try.
// THIS IS MY urban.js FILE
const {
SlashCommandBuilder,
SlashCommandStringOption
} = require('#discordjs/builders');
const {
request
} = require('undici');
const {
MessageEmbed
} = require('discord.js');
const wait = require('node:timers/promises').setTimeout;
const trim = (str, max) => (str.length > max ? `${str.slice(0, max - 3)}...` : str);
async function getJSONResponse(body) {
let fullBody = '';
for await (const data of body) {
fullBody += data.toString();
}
return JSON.parse(fullBody);
}
module.exports = {
data: new SlashCommandBuilder()
.setName('urban')
.setDescription('Replies with definition!')
.addStringOption(option =>
option.setName('input')
.setDescription('word to define')
.setRequired(true)),
async execute(interaction) {
const term = interaction.options.getString('input')
console.log(term);
const query = new URLSearchParams({
term
});
const dictResult = await request(`https://api.urbandictionary.com/v0/define?${query}`);
const {
list
} = await getJSONResponse(dictResult.body);
if (!list.length) {
return interaction.editReply(`No results found for **${term}**.`);
}
const [answer] = list;
const embed = new MessageEmbed()
.setColor('#EFFF00')
.setTitle(answer.word)
.setURL(answer.permalink)
.addFields({
name: 'Definition',
value: trim(answer.definition, 1024)
}, {
name: 'Example',
value: trim(answer.example, 1024)
}, {
name: 'Rating',
value: `${answer.thumbs_up} thumbs up. ${answer.thumbs_down} thumbs down.`,
}, );
interaction.editReply({
embeds: [embed]
});
},
};
// THIS IS THE INDEX JS FILE. It's not a filepath issue.
const {
token
} = require('./config.json');
const fs = require('node:fs');
const path = require('node:path');
const {
Client,
Collection,
Intents,
MessageEmbed,
DiscordAPIError
} = require('discord.js');
const wait = require('node:timers/promises').setTimeout;
const client = new Client({
intents: [Intents.FLAGS.GUILDS]
});
client.commands = new Collection();
const commandsPath = path.join(__dirname, 'commands');
const commandFiles = fs.readdirSync(commandsPath).filter(file => file.endsWith('.js'));
const eventsPath = path.join(__dirname, 'events');
const eventFiles = fs.readdirSync(eventsPath).filter(file => file.endsWith('.js'));
for (const file of eventFiles) {
const filePath = path.join(eventsPath, file);
const event = require(filePath);
if (event.once) {
client.once(event.name, (...args) => event.execute(...args));
} else {
client.on(event.name, (...args) => event.execute(...args));
}
}
for (const file of commandFiles) {
const filePath = path.join(commandsPath, file);
const command = require(filePath);
// Set a new item in the Collection
// With the key as the command name and the value as the exported module
client.commands.set(command.data.name, command);
}
client.once('ready', () => {
console.log('Ready!');
});
client.on('interactionCreate', async interaction => {
if (!interaction.isCommand()) return;
const command = client.commands.get(interaction.commandName);
await interaction.deferReply({
ephemeral: true
});
await wait(4000);
if (!command) return;
try {
await command.execute(interaction);
} catch (error) {
console.error(error);
}
});
console.log(token)
client.login(token)
When I console.log(interaction.options.getString('input'))
it just gives me null.
when I console.log interaction it gives me a detailed account of the command and everything else like the user that sent it. But none of the information from the SlashCommand data. Please help.

JavaScript Azure Blob Storage move blob

I have a NodeJS backend which use the official blob storage library (#azure/storage-blob) from Microsoft to manage my Blob Storage:
https://www.npmjs.com/package/#azure/storage-blob
It is necessary to move a blob from one folder, to another.
Unfortunately I can't find any documentation for that.
What I did until now is:
const { BlobServiceClient } = require("#azure/storage-blob");
const blobServiceClient = BlobServiceClient.fromConnectionString(process.env.storageconnection);
const containerClient = blobServiceClient.getContainerClient('import');
const blobClient = containerClient.getBlobClient('toImport/' + req.body.file);
const downloadBlockBlobResponse = await blobClient.download();
... do some stuff with the value of the files
Like you can see in the code, I read a file from folder "toImport". After that I want to move the file to another folder "finished". Is that possible? Maybe I need to create a copy of the file and delete the old one?
As such move operation is not supported in Azure Blob Storage. What you have to do is copy the blob from source to destination, monitor the copy progress (because copy operation is asynchronous) and delete the blob once the copy is complete.
For copying, the method you would want to use is beginCopyFromURL(string, BlobBeginCopyFromURLOptions).
Please see this code:
const { BlobServiceClient } = require("#azure/storage-blob");
const connectionString = "DefaultEndpointsProtocol=https;AccountName=account-name;AccountKey=account-key;EndpointSuffix=core.windows.net";
const container = "container-name";
const sourceFolder = "source";
const targetFolder = "target";
const blobName = "blob.png";
async function moveBlob() {
const blobServiceClient = BlobServiceClient.fromConnectionString(connectionString);
const containerClient = blobServiceClient.getContainerClient(container);
const sourceBlobClient = containerClient.getBlobClient(`${sourceFolder}/${blobName}`);
const targetBlobClient = containerClient.getBlobClient(`${targetFolder}/${blobName}`);
console.log('Copying source blob to target blob...');
const copyResult = await targetBlobClient.beginCopyFromURL(sourceBlobClient.url);
console.log('Blob copy operation started successfully...');
console.log(copyResult);
do {
console.log('Checking copy status...')
const blobCopiedSuccessfully = await checkIfBlobCopiedSuccessfully(targetBlobClient);
if (blobCopiedSuccessfully) {
break;
}
} while (true);
console.log('Now deleting source blob...');
await sourceBlobClient.delete();
console.log('Source blob deleted successfully....');
console.log('Move operation complete.');
}
async function checkIfBlobCopiedSuccessfully(targetBlobClient) {
const blobPropertiesResult = await targetBlobClient.getProperties();
const copyStatus = blobPropertiesResult.copyStatus;
return copyStatus === 'success';
}
moveBlob();
The previous best solution seem working but I don't like use an infinite loop.
So this is an alternative way to move blob file
const move = async (
fileName: string,
src: string,
dest: string
) => {
try {
const = blobServiceClient = BlobServiceClient.fromConnectionString();
logger.info(`Move storage file [ ${src} -> ${dest} | ${fileName} ]`);
const srcContainerClient = blobServiceClient.getContainerClient(src);
const destContainerClient =
blobServiceClient.getContainerClient(dest);
const blobClient = srcContainerClient.getBlobClient(fileName);
const downloadBlockBlobResponse = await blobClient.download();
const buffer = await streamToBuffer(
downloadBlockBlobResponse.readableStreamBody!
);
blobClient.delete();
const blockBlobClient = containerClient.getBlockBlobClient(fileName);
await blockBlobClient.upload(buffer, buffer.length);
return `${this.storageUrl}/${containerClient.containerName}/${fileName}`;
} catch (e) {
throw new Error(
`Fail to move storage file [ ${src} -> ${dest} | ${fileName} ]`
);
}
};
const streamToBuffer = async (readableStream: NodeJS.ReadableStream): Promise<Buffer> => {
return new Promise((resolve, reject) => {
const chunks: Buffer[] = [];
readableStream.on("data", (data) => {
chunks.push(data instanceof Buffer ? data : Buffer.from(data));
});
readableStream.on("end", () => {
resolve(Buffer.concat(chunks));
});
readableStream.on("error", reject);
});
};

How to pass parameter message as text in openpgp JS

What I'm trying to do:
get some Azure storage blobs from container DIDE and encrypt them with RSA 2048 and upload them in other container called encrypted-dide
These blobs are downloaded through a stream(here Microsoft did a good job https://learn.microsoft.com/en-us/azure/storage/blobs/storage-quickstart-blobs-nodejs#upload-blobs-to-a-container) and recomposed by func. streamToString(readableStream)
(I'm not using openpgp JS streams as I don't know if Microsoft streams are the same with NodeJs ones)
My code works as expected with unecrypted text and upload blobs in the supposedly encryped container encrypted-dide
I have followed the official documentation of openpgp js and some Internet resources.
The error I am getting is Error: Parameter [message] needs to be of type Message in openpgp JS
the publicKey is harcoded in the file keys.js and and is exported like this:
const publicKey = `-----BEGIN PGP PUBLIC KEY BLOCK-----
xsBNBGDgi3gBCADcZqIcczPDAx3+os5cCFVgaoT62Y+5rRvwPGPaPKKA1ajw
7NvoxS0RsJbqYAwNk0IEneoZvgSPpqkehGQCOBdsEhjcEgxVxaSlbbgPJkPh
avjTBDUhr6pIUc+MkSX7eh5LdkgWRSfzZdLXX2es5ycM5R1ZryzPTAenZh7D
l1g1x9TsyX+scI7gAtuyfbzAybYVqYMIvcHYZdIi8m6pGmxIqb0QW6sgO6nG
GyjVgxLDyMnHzYMInFRmKUV8XUUw9ECLZ6ioW4rthmpjoswh9vmP6vWI9OL/
Y7Zb3xY5XnIT6UFSpAHS5V/TNbEUD/EpoNtEI30bUl2X35UM277fUxetABEB
AAHNG0pvbiBTbWl0aCA8am9uQGV4YW1wbGUuY29tPsLAigQQAQgAHQUCYOCL
eAQLCQcIAxUICgQWAAIBAhkBAhsDAh4BACEJEGHAYnRSOf5GFiEExGMJvxnV
v1dXecI0YcBidFI5/kY5PAgAxL10QcUZIrxRXQIrqk04ZDhO4ehMirPqH/KT
L/MeHppHFqV06Fm4JDAOpGyh8lgleLwP4P9Lrod3AVSOKSX48u+UM/Bo4LtG
foAntS+tC9RjWlpR6PZ0aJA8SqHKLCnkaUvz7wv/M55fgGxeeQbhOLutNxN4
L8rCNhPo3UbWwoB+ifgQ9S4bv4kgyJxXYinyGYG0CD67YxQKxiAt58qjsdmK
x4uKCoFbHd1Oa4wfr6ezXet+2hCQvsf8eJV88+qL7TmpSe3ypiTWHNgxymNx
v77SlOkkzayJVWxrWtFU8ZoatlsfOP3A5tToio2rEhCHcnqYl4KtF1a0WUR8
KG+pJc7ATQRg4It4AQgA0Q2uZL9TIqGWtNzeAygdG0C3o+D+MoEYI/Qx0A6X
aZv7/1v84V++lRD0iuIMUlBgFEJWMsHF7cN1EMlUV1lRxOzyKTv+0FqyoSTr
bWexA+jG/Nb3Q8vSX1+eVHvm1+2H7AGhBH2szVmXeH15bGNaOaw03EmG5pCh
CIaCoXYUXKoavsa+C8827lGSuqLs1uRniCmIjQvkQSZg7a0IH6dpMIpxdHPh
h9Zyt8e74WwfmXW/be6cjWRI9FgBzl9U5EQEEVO1JdLvfzEEXkNthyAAhl+P
Z1oTR2PSs4ZUlYdb3MQrt7XoKeEOqCHHxoHB3gsj+75Jnc/aAbM+hb13imAJ
iwARAQABwsB2BBgBCAAJBQJg4It4AhsMACEJEGHAYnRSOf5GFiEExGMJvxnV
v1dXecI0YcBidFI5/kZYSQgAop0OsPV11O/fzbZ+oEabC3Ye9hNGapJQNdmJ
MJkiJg7Hnl1FO4MDtHK5OJ4YePFAqtlKRDIBCALPiN0E2v9+3yAafs6TQDc9
Lg3iIPDOnrXv7J7pv2WPnnue4o8Gkggpa+wEjbQJcUBLX311xJGBG4pSNIVN
FJcsl1fGoaxXB5ANPy/+UNMv0l/7cQWDzSw8V9WH10SO2Q4dQF7Zxw+UgBdb
mRVXWNHkcTs81WA/hYtAuLw0O5Q1QWfbXzlTJGNPy/lMMsxLF6La8fBPHlE0
CjYd4ZH9HgOvpCACjRtbc1jywaZJEisO2aJcO2BaozSzYUmkr5sH2wjSKcMS
nLviCw==
=Wg0i
-----END PGP PUBLIC KEY BLOCK-----`
The code is:
const { BlobServiceClient } = require('#azure/storage-blob');
// const { v1: uuidv1 } = require('uuid');
// const stream = require('stream').promises
const openpgp = require('openpgp');
// import * as openpgp from 'openpgp'
const { publicKey } = require('./keys')
async function main() {
const AZURE_STORAGE_CONNECTION_STRING = process.env.AZURE_STORAGE_CONNECTION_STRING;
const blobServiceClient = BlobServiceClient.fromConnectionString(AZURE_STORAGE_CONNECTION_STRING);
const containerClient = blobServiceClient.getContainerClient("uploadebs");
const containerEncryptedFiles = blobServiceClient.getContainerClient("encrypted-dide");
await containerEncryptedFiles.createIfNotExists("encrypted-dide")
// console.log(await openpgp.readKey({ armoredKey: publicKey })) <- THIS WORKS!
for await (const blob of containerClient.listBlobsFlat()) {
if (blob.name.match('^DIDE*')) {
const blockBlobClient = containerClient.getBlockBlobClient(blob.name);
const encryptedblockBlobClient = containerEncryptedFiles.getBlockBlobClient(blob.name)
blockBlobClient.download(0)
.then(downloadBlockBlobResponse => streamToString(downloadBlockBlobResponse.readableStreamBody))
.then(blobAsString => openpgp.encrypt({
message: openpgp.createMessage({ text: blobAsString }), // input as Message object
publicKeys: openpgp.readKey({ armoredKey: publicKey }),
}))
// BELOW LINE, SENDS TEXT IN BLOBS, ENCRYPTED OR NOT THROUGH FUNC UPLOAD
.then(encrypted => {encryptedblockBlobClient.upload(encrypted, encrypted.length)})
}
}
}
async function streamToString(readableStream) {
return new Promise((resolve, reject) => {
const chunks = [];
readableStream.on("data", (data) => {
chunks.push(data.toString());
});
readableStream.on("end", () => {
resolve(chunks.join(""));
});
readableStream.on("error", reject);
});
}
main().then(() => console.log('Done')).catch((ex) => console.log(ex.message));
openpgp.createMessage returns a Promise. So you need to do .then or add await before it.
Same with penpgp.readKey. It is also a promise.
For example from the Doc:
const publicKey = await openpgp.readKey({ armoredKey: publicKeyArmored });
const encrypted = await openpgp.encrypt({
message: await openpgp.createMessage({ text: 'Hello, World!' }), // input as Message object
publicKeys: publicKey, // for encryption
privateKeys: privateKey // for signing (optional)
});
EDIT2:
Without using await.
.then(blobAsString => {
return Promise.all([openpgp.createMessage({ text: blobAsString }), openpgp.readKey({ armoredKey: publicKey })])
.then(([message, publicKeys ])=>{
return openpgp.encrypt({
message,
publicKeys,
});
});
})
Used like this:
.then(blobAsString => {
return Promise.all([openpgp.createMessage({ text: blobAsString }), openpgp.readKey({ armoredKey: publicKey })])
.then(([message, publicKeys ])=>{
return openpgp.encrypt({
message,
publicKeys,
})
})
.then(encrypted => {encryptedblockBlobClient.upload(encrypted, encrypted.length)});;
})

Parse-server sharp package in beforeSaveFile

I want to use this package: sharp in beforeSaveFile trigger but it doesn't work. beforeSaveFile doesn't change anything.
My codes:
Parse.Cloud.define('test', async (req) => {
try {
const Resim = Parse.Object.extend('Resim')
const obj = new Resim()
const { photo } = req.params
let uploadedFile = await new Parse.File(
'galleryFile',
{ base64: photo },
'image/png'
)
obj.set('photo', uploadedFile)
const data = await obj.save()
return data
} catch (error) {
throw error
}
})
Parse.Cloud.beforeSaveFile(async (req) => {
const image = await sharp(req.file).resize(256)
return image
})
Thanks for help.
I figured out. This is the solution:
Parse.Cloud.beforeSaveFile(async (req) => {
const file = req.file
const fileData = await file.getData()
const str = fileData.toString('base64')
const imageBuffer = Buffer.from(str, 'base64')
const newImageBuffer = await sharp(imageBuffer)
.resize(800, 800)
.webp({ quality: 70, lossless: true })
.toBuffer()
return new Parse.File(
'image',
{ base64: newImageBuffer.toString('base64') },
'image/webp'
)
})

php openssl_seal equivalent in Node.js

I have a code snippet in php which I would like to move into node.js but I cannot seem to find the right way to do it.
class EncryptService
{
const PUBLIC_CERT_PATH = 'cert/public.cer';
const PRIVATE_CERT_PATH = 'cert/private.key';
const ERROR_LOAD_X509_CERTIFICATE = 0x10000001;
const ERROR_ENCRYPT_DATA = 0x10000002;
public $outEncData = null;
public $outEnvKey = null;
public $srcData;
public function encrypt()
{
$publicKey = openssl_pkey_get_public(self::PUBLIC_CERT_PATH);
if ($publicKey === false) {
$publicKey = openssl_pkey_get_public("file://".self::PUBLIC_CERT_PATH);
}
if ($publicKey === false) {
$errorMessage = "Error while loading X509 public key certificate! Reason:";
while (($errorString = openssl_error_string())) {
$errorMessage .= $errorString . "\n";
}
throw new Exception($errorMessage, self::ERROR_LOAD_X509_CERTIFICATE);
}
$publicKeys = array($publicKey);
$encData = null;
$envKeys = null;
$result = openssl_seal($this->srcData, $encData, $envKeys, $publicKeys);
if ($result === false)
{
$this->outEncData = null;
$this->outEnvKey = null;
$errorMessage = "Error while encrypting data! Reason:";
while (($errorString = openssl_error_string()))
{
$errorMessage .= $errorString . "\n";
}
throw new Exception($errorMessage, self::ERROR_ENCRYPT_DATA);
}
$this->outEncData = base64_encode($encData);
$this->outEnvKey = base64_encode($envKeys[0]);
}
};
The problem is that I cannot find an implementation of the openssl_sign in Javascript anywhere. I do need to keep this structure because I use both outEncData and outEnvKey.
I managed to find the equivalent implementation of openssl_sign with the crypto package but nothing for openssl_seal.
LE added working solution as an answer
OK I've spent some time to figure this out, in short it is now in the repo: ivarprudnikov/node-crypto-rc4-encrypt-decrypt. But we want to follow SO rules here.
Below assumes that you have public key for signing the generated key and private key for testing if all is great.
Randomly generated secret key used for encryption:
const crypto = require('crypto');
const generateRandomKeyAsync = async () => {
return new Promise((resolve, reject) => {
crypto.scrypt("password", "salt", 24, (err, derivedKey) => {
if (err) reject(err);
resolve(derivedKey.toString('hex'));
});
});
}
Encrypt data with the generated key and then encrypt that key with a given public key. We want to send back both encrypted details and encrypted key as we expect the user on another side to have private key.
const crypto = require('crypto');
const path = require('path');
const fs = require('fs');
const encryptKeyWithPubAsync = async (text) => {
return new Promise((resolve) => {
fs.readFile(path.resolve('./public_key.pem'), 'utf8', (err, publicKey) => {
if (err) throw err;
const buffer = Buffer.from(text, 'utf8');
const encrypted = crypto.publicEncrypt(publicKey, buffer);
resolve(encrypted.toString('base64'));
});
});
}
const encryptStringAsync = async (clearText) => {
const encryptionKey = await generateRandomKeyAsync();
const cipher = await crypto.createCipheriv("RC4", encryptionKey, null);
const encryptedKey = await encryptKeyWithPubAsync(encryptionKey);
return new Promise((resolve, reject) => {
let encryptedData = '';
cipher.on('readable', () => {
let chunk;
while (null !== (chunk = cipher.read())) {
encryptedData += chunk.toString('hex');
}
});
cipher.on('end', () => {
resolve([encryptedKey, encryptedData]); // return value
});
cipher.write(clearText);
cipher.end();
});
}
So now we can encrypt the details:
encryptStringAsync("foo bar baz")
.then(details => {
console.log(`encrypted val ${details[1]}, encrypted key ${details[0]}`);
})
Will print something like:
encrypting foo bar baz
encrypted val b4c6c7a79712244fbe35d4, encrypted key bRnxH+/pMEKmYyvJuFeNWvK3u4g7X4cBaSMnhDgCI9iii186Eo9myfK4gOtHkjoDKbkhJ3YIErNBHpzBNc0rmZ9hy8Kur8uiHG6ai9K3ylr7sznDB/yvNLszKXsZxBYZL994wBo2fI7yfpi0B7y0QtHENiwE2t55MC71lCFmYtilth8oR4UjDNUOSrIu5QHJquYd7hF5TUtUnDtwpux6OnJ+go6sFQOTvX8YaezZ4Rmrjpj0Jzg+1xNGIIsWGnoZZhJPefc5uQU5tdtBtXEWdBa9LARpaXxlYGwutFk3KsBxM4Y5Rt2FkQ0Pca9ZZQPIVxLgwIy9EL9pDHtm5JtsVw==
To test above assumptions it is necessary first to decrypt the key with the private one:
const decryptKeyWithPrivateAsync = async (encryptedKey) => {
return new Promise((resolve) => {
fs.readFile(path.resolve('./private_key.pem'), 'utf8', (err, privateKey) => {
if (err) throw err;
const buffer = Buffer.from(encryptedKey, 'base64')
const decrypted = crypto.privateDecrypt({
key: privateKey.toString(),
passphrase: '',
}, buffer);
resolve(decrypted.toString('utf8'));
});
});
}
After key is decrypted it is possible to decrypt the message:
const decryptWithEncryptedKey = async (encKey, encVal) => {
const k = await decryptKeyWithPrivateAsync(encKey);
const decipher = await crypto.createDecipheriv("RC4", k, null);
return new Promise((resolve, reject) => {
let decrypted = '';
decipher.on('readable', () => {
while (null !== (chunk = decipher.read())) {
decrypted += chunk.toString('utf8');
}
});
decipher.on('end', () => {
resolve(decrypted); // return value
});
decipher.write(encVal, 'hex');
decipher.end();
});
}
Hope this answers the question.
The final and working version that worked for me. My problem was that I used an 128bit random key encrypt the data, instead 256bit worked in the end.
The encryption works in JS and it can be decrypted in php with the openssl_open using your private key, which was what I asked in the original question.
const crypto = require('crypto');
const path = require('path');
const fs = require('fs');
const encryptMessage = (message) => {
const public_key = fs.readFileSync(`${appDir}/certs/sandbox.public.cer`, 'utf8');
const rc4Key = Buffer.from(crypto.randomBytes(32), 'binary');
const cipher = crypto.createCipheriv('RC4', rc4Key, null);
let data = cipher.update(message, 'utf8', 'base64');
cipher.final();
const encryptedKey = crypto.publicEncrypt({
key: public_key,
padding: constants.RSA_PKCS1_PADDING
}, rc4Key);
return {
'data': data,
'env_key': encryptedKey.toString('base64'),
};
};

Categories

Resources