unzip encrypted file with AES-256 node.js - javascript

I'm trying to decrypt zip file using crypto provided file is in s3 storage and I have password for the file and no info for IV.
I'm using cryptoDecipher but getting error cryptoDecipher is deprecated. I saw some post saying use createDecipheriv but I don't have any IV that I can use.
below is a sample code -
function demo(entry){
password = 'mypassword';
algorithm = 'aes-256-cbc';
let decrypt = crypto.createDecipher(algorithm,password)
let res = entry.stream().pipe(decrypt);
const uploadParams = {
Body:res,
Bucket:myS3bucket,
key:myfilename,
}
uploadfile(uploadParams)
}
I'm using unzipper to unzip file and getting 'entry as object for file so just using that object in demo function'
help me out as I'm new to streams and crypto lib.

Related

Download files from Azure blob storage

There is html code written for download button.
The complete Sharepoint 2013 hosted application functionality has JS code. There is WCF solution using C# to get data from SAP system.
There is one page in application which has download button. Once clicked by the user, the file should get downloaded from Azure blob storage.
Kindly help how we can achieve this.
I have tested in my environment
You can use the below javascript function to download files from Azure blob storage :
async function main() {
var fs = require('fs');
const { BlobServiceClient, StorageSharedKeyCredential } = require("#azure/storage-blob");
const account = "storage account name";
const accountKey = "storage account key"
const sharedKeyCredential = new StorageSharedKeyCredential(account, accountKey);
const blobServiceClient = new BlobServiceClient(
`https://${account}.blob.core.windows.net`,
sharedKeyCredential);
const containerClient = blobServiceClient.getContainerClient("container name");
const blobClient = containerClient.getBlobClient("blob file name to be downloaded");
const response = await blobClient.downloadToFile("blob file name to be downloaded");
main();

How can I get window.crypto.subtle to output the same signature as the 'crypto' js library?

I'm wanting to use the built in browser crypto object instead of importing the crypto library in my browser project.
I want to not need this.
npm i crypto
The following code illustrates trying to sign a simple message using both libraries, however I get a different result when using the built in crypto object. The outputs are logged to console.
// START CRYPTO LIBRARY METHOD
import crypto from 'crypto';
const HMAC_SHA256_KEY = {
API_KEY: '***',
SECRET_KEY: '***'
};
const queryString = `timestamp=${(new Date().getTime())}`;
const signature = crypto
.createHmac('sha256', HMAC_SHA256_KEY.SECRET_KEY)
.update(queryString)
.digest('hex')
console.log("standard encrypt", signature);
// START NATIVE LIBRARY METHOD
const getUtf8Bytes = (str: string) => {
return new Uint8Array(
[...(unescape(encodeURIComponent(str)))].map(c => c.charCodeAt(0))
);
};
// #ts-ignore
const builtInCrypto = window.crypto || window.msCrypto;
builtInCrypto.subtle.importKey(
'raw',
getUtf8Bytes(HMAC_SHA256_KEY.SECRET_KEY),
{
name: 'HMAC', hash: 'SHA-256'
},
true, ['sign']
).then(key => {
builtInCrypto.subtle.sign(
'HMAC',
key,
getUtf8Bytes(queryString))
.then(signature => {
console.log('builtIn Signature', btoa(String.fromCharCode(...(new Uint8Array(signature)))));
})
})
Clearly I'm doing something wrong, but what? Why am I getting a different output for the native encryption?
For the same values of HMAC_SHA256_KEY.SECRET_KEY and queryString (the last parameter depends on time and therefore has a different value for each run) both scripts return the same HMac but in different encodings, resulting in different output. In the NodeJS / crypto code the HMac is hex encoded, in the JavaScript / Web Crypto API code Base64 encoded.
To make sure that the output is identical, the same encoding must be used in both scripts. Either the HMac in the JavaScript / Web Crypto API code must also be hex encoded, see e.g. here for a suitable method, or the HMac in the NodeJS / crypto code must be Base64 encoded (by passing 'base64' instead of 'hex' as argument of digest).

How to store byte array into local file in JavaScript?

I was working with openssl certificate.
So what I want to achieve is I download the certificate from my API, it returns me bytes arrays. For example:
0�
g0�
' *�H��
��
�
0�
And I try to write these into a file, and use some other function to read and convert to PEM file so I can access it with another API. (The initial format of this cert is PFX).
I've checked and if I download the certificate via Postman, via the 'Send and Download' button I get something like this:
0‚
g0‚
' *†H†÷
 ‚
‚
0‚
It is slightly different than what I direct wrote into a file. How can I convert from that to this? I faced error from the next step is because this is not a valid PFX file. The error from the other API reads as below:
DecodeToAsn:
ASN.1 length cannot be more than 4 bytes in definite long-form.
This error typically occurs when trying to decode data that is not ASN.1
A common cause is when decrypting ASN.1 data with an invalid password,
which results in garbage data. An attempt is made to decode the garbage bytes
as ASN.1, and this error occurs...
--DecodeToAsn
Failed to decode PFX ASN.1 for integrity verification.
So how can I store bytes arrays into local file correctly? Or is there any way to convert the byte arrays to what I have via Postman?
As of now I only write the bytearray directly to the file, below are the codes:
async function downloadCertificate() {
try {
let pfx = new chilkat.Pfx();
let downloadedPfxByteArray = await Api.downloadCertificate(id);
let pfxFileLocation = `${process.cwd()}\\media\\CERTFILE.pfx`;
fs.writeFileSync(pfxFileLocation, downloadedPfxByteArray);
pfx.LoadPfxFile(pfxFileLocation, 'password');
let strPem = pfx.ToPem();
console.log(strPem);
return pemValue;
} catch (error) {
console.log(`READ PFX FAIL ! ${error}`);
}
}
Thanks for reading and appreciates if anyone could help!
#!/usr/bin/env node
const fetch = require('node-fetch');
const fs = require('fs').promises;
async function main() {
await fs.writeFile(
'/tmp/so-58603015.pfx',
Buffer.from(await (await fetch('…url…')).arrayBuffer())
);
}
main();

Node HmacSHA1 Seed

I'm trying to send a SOAP request via Node, talking to a service which is secured with WSS.
I need to sign the XML response with a SignedInfo element which requires me combining a Nonce Binary secret I generated, with a Nonce binary secret returned from the initial token request - PSHA1 format.
I've been able to validate this using Java, by utilising the following class (Where the secret is my client nonce and the seed is the server nonce):
https://github.com/apache/wss4j/blob/trunk/ws-security-common/src/main/java/org/apache/wss4j/common/derivedKey/P_SHA1.java#L57
With the following Java code:
Mac mac = Mac.getInstance("HmacSHA1");
SecretKeySpec key = new SecretKeySpec(getSharedKey(), "HmacSHA1");
mac.init(key);
String bytesToSign = "<XML_TO_SIGN_GOES_HERE>";
String signature = Base64.encodeBytes(mac.doFinal(bytesToSign.getBytes()));
I need to do this in a Node project though, I've looked at the Crypto API and numerous plugins but I'm unable to generate the same signature.
How do I specify a seed for a HmacSHA1 using node?
I managed to get there in the end, there's an NPM module called psha1 (https://www.npmjs.com/package/psha1).
Using that library I created the following a generateSignature module which looks as follows:
const crypto = require('crypto');
const psha1 = require('psha1');
export const generateSignatureValue = ({
clientSecret,
serverSecret,
messageToSign,
}) => {
const secretKey =
psha1(clientSecret, serverSecret, 256);
const hash =
crypto
.createHmac('sha1', Buffer.from(secretKey, 'base64'))
.update(messageToSign)
.digest('binary');
return Buffer
.from(hash, 'binary')
.toString('base64');
};
export default generateSignatureValue;
This gives me the desired output :)

Encrypt in nodeJS and Decrypt in Javascript

I am encrypting text in node JS by using node-RSA and passing it to client(javascript), in which JSEncrypt library is using,but all the time the decrypted message is coming null. Public key and private Key is developing on nodeJS server, encrypting with Public key and decrypting on javascript side with Private Key .
This is not happening right!!!!
Can anyone tell which library i should use in javascript to decrypt the message coming from nodejs(using Node-RSA).OR any other IDEA!!
We are already using HTTPS but our use case is such that we have a broker between it.. and its not trusted broker, and we are forced to use it.. so we would like to use encryption decryption.. Although we have trusted people in our client side, so we are decrypting at client side.
I used CryptoBrowserify to encrypt at javascript (client side)
import CryptoBrowserify from 'crypto-browserify';
public encryptStringWithRsaPublicKey(data: string, publicKey: string): string {
var encrypted = CryptoBrowserify.publicEncrypt( publicKey,new Buffer(data));
return encrypted.toString('Base64');
}
And crypto to dedcrypt at Nodejs
decrypt = function(privateKey, data) {
var crypto = require('crypto');
var buffer = new Buffer(data, 'base64');
var decrypted = crypto.privateDecrypt(privateKey, buffer);
return decrypted.toString('utf8')
};
Nodejs has its builtin cryto library,it is optimized and tested, recommend to use that: https://nodejs.org/api/crypto.html

Categories

Resources