Reputation: 109
Motivation: I want to make a browser-based hashing utility so users can compute file hashes without installing software.
The approach I'm considering is a static page with "a file upload button" (except no upload takes place): the user picks a file, and the script computes and displays its hash.
So let's say we have this element on the page:
<input id="file-hasher" type="file" />
This creates a button that allows the users of the web page to select a file via an OS "File open..." dialog in the browser.
Let's say the user clicks said button, selects a file in the dialog, then clicks the "Ok" button to close the dialog.
The selected file name is now stored in:
document.getElementById("file-hasher").value
Here, I'm hoping to use a library like https://github.com/bitwiseshiftleft/sjcl/ to compute the hash of the chosen file. Is there a way to do this or does the browser's security model get in the way?
Upvotes: 2
Views: 4065
Reputation: 12027
Yes, you can select a file using the file element, and take a hash of the file locally, 'in-browser', using javascript. The browser's security model does not prevent this; and the hash function from the native Web Crypto API can be used, so there is no need for any external crypto libraries.
Here is a working example:
function hashfile() {
readbinaryfile(fileselector.files[0])
.then(function(result) {
result = new Uint8Array(result);
return window.crypto.subtle.digest('SHA-256', result);
}).then(function(result) {
result = new Uint8Array(result);
var resulthex = Uint8ArrayToHexString(result);
divresult.innerText = 'result: ' + resulthex;
});
}
function readbinaryfile(file) {
return new Promise((resolve, reject) => {
var fr = new FileReader();
fr.onload = () => {
resolve(fr.result)
};
fr.readAsArrayBuffer(file);
});
}
function Uint8ArrayToHexString(ui8array) {
var hexstring = '',
h;
for (var i = 0; i < ui8array.length; i++) {
h = ui8array[i].toString(16);
if (h.length == 1) {
h = '0' + h;
}
hexstring += h;
}
var p = Math.pow(2, Math.ceil(Math.log2(hexstring.length)));
hexstring = hexstring.padStart(p, '0');
return hexstring;
}
<h2>File Hash</h2>
<div>
Select file to take hash of:
<br/>
<input type="file" id="fileselector" onchange="javascript:hashfile();">
</div>
<br/>
<div id="divresult"></div>
Upvotes: 7
Reputation: 109
The standard browser security model allows you to have the user pick a file and do what you will with it. I'm an older guy and thought surely this kinda mingling with a user's parts would require additional hoops/consent. So @ceving 's answer was best: "Do it and you will see."
Here's a link to a good article: https://humanwhocodes.com/blog/2012/05/08/working-with-files-in-javascript-part-1/
Apologies for not trying first before posting.
Upvotes: 0