I would like to obtain the same hash of a file on server as on the client.
I tried:
- creating a form to upload
- computing the hash with
node-forgeclient-side - computing the hash on Linux command-line
- uploading the file through the form
- grabbing the file server-side as a blob
- reading contents with .text() server-side
- computing the hash server-side with
node-forge
I am stuck at 7.
So, first I upload a file through a form
<form method="POST" action="?/upload" enctype="multipart/form-data">
<input
id="csvFile"
name="csvFile"
type="file"
on:change={handleChange}
/>
<button type="submit" class="btn">Upload</button>
</form>
and I compute the hash of a file in the browser with node-forge:
function handleChange(event) {
let files = event.target.files;
const file = files[0]
reader = new FileReader();
reader.onload = function (event) {
var binary = event.target.result;
var md = forge.md.sha256.create();
sha256 = md.update(binary).digest().toHex();
};
reader.readAsBinaryString(f);
}
This computes a hash that is the same as when I execute it from the command line with sha256sum, so it is reliable.
However, when I upload the file and process it on SvelteKit, I am unable to obtain the same hash. I am thinking this is because the filename or something else is missing from the resulting blob compared to what is available in the browser.
export const actions = {
upload: async ({ request }) => {
const formData = await request.formData()
const file = await formData.get(`csvFile`) as File;
const contents = await file.text()
const md = forge.md.sha256.create();
md.update(contents);
const sha256 = md.digest().toHex()
}
}
I cannot use new FileReader() here because I am in a Node environment.
How can I create the exact same hash server-side and client-side? Do I need to add the filename or something to obtain the same hash as from the command line?
Thanks in advance!
Reading as text implies some encoding. The best approach is probably to read the data as simple array buffers in both cases to be consistent.
You can use the asynchronous
arrayBuffer()function on the file in both cases. (If you want to target older browsers, you can also useFileReader.readAsArrayBuffer()on the client.)In both cases you can convert the data to a hash-able string, e.g. by converting the individual bytes and joining them: