How to store byte array into local file in JavaScript? - 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();

Related

unzip encrypted file with AES-256 node.js

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.

Convert Buffer (image) to file

I'm looking for the best way to send image files to my server using Apollo Express, and Node.
Getting the information there doesn't seem to be an issue, I convert the object into a string but can't find out how to convert it back to a regular file object to store away.
What I have so far;
JS - let buffer = await toBase64(file);
Through Apollo server..
Node - let buffer = Buffer.from(args.image, 'base64');
This gives me a Buffer. I'm unsure how to proceed with NodeJS to convert this back to a file object.
Thanks
I hope this will be helpfull for you
const file = new File([
new Blob(["decoded_base64_String"])
], "output_file_name");
You can use one of the various write or writeFile methods which accept a Buffer.
const fs = require("fs");
let buffer = Buffer.from(
"iVBORw0KGgoAAAANSUhEUgAAAAgAAAAGCAIAAABxZ0isAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAQSURBVBhXY/iPAwygxP//AAjcj3EdtT3BAAAAAElFTkSuQmCC",
"base64"
);
fs.writeFile("pic.png", buffer, (err) => {
if (err) throw err;
console.log("The file has been saved!");
});

How to save big object to file nodejs?

I have a big object that I need to send from server (nodejs) to client.
But every time I try send I get "invalid string length" error.
And it's ok, because the object is really big. That's why I'd like to save it to file and then send the file to client.
I don't know the depth of the object. The object itself is and octree.
I don't have any code of saving an object to file, because every time I think about this it leads me to stringify the object, that latter leads to "invalid string length".
Here is a screenshot of the object. Every q(n) key has the same recursive structure as result key.
Thanks!
Firstly try to save in a JSON file and send JSON file directly to client-side
const fs = require('fs');
fs.writeFileSync("file_name.json", data);
res.header("Content-Type",'application/json');
res.sendFile(path.join(__dirname, 'file_name.json'));
A good solution to handling large data transfer between server and client is to stream the data.
Pipe the result to the client like so.
const fs = require('fs');
const fileStream = fs.createReadStream("path_to_your_file.json");
res.writeHead(206, {'Content-Type': 'application/json'})
fileStream.pipe(response)
or follow this blog which stringifies each element at a time and concatenates them.
I will suggest you stream it though.
You could try something like this, I'm unsure if Express would throw the same length error by using res.json.
// Assuming you're using Express and data is valid JSON.
res.json(data);

Use pdf-table-extractor directly with axios?

This script is run in server using NodeJS,
I want to use pdf-table-extractor with remote file input directly from axios, is that can be done ?
here is what i have tried
const axios = require('axios')
const pdf_table_extractor = require("pdf-table-extractor")
const getPDF = await axios.get(`domain/a.pdf`,{responseType: 'arraybuffer'})
pdf_table_extractor(new Uint8Array(getPDF.data))
the error say The argument 'path' must be a string or Uint8Array without null bytes. Received Uint8Array(118456)
pdf-table-extractor is expecting a filepath and you are passing a typed array. It can't work this way.
There are many options, one of them is to save the data from getPDF.data to disk using writeFile, and then provide the path of the saved file to pdf_table_extractor.

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 :)

Categories

Resources