diafygi / webcrypto-examples

Web Cryptography API Examples Demo: https://diafygi.github.io/webcrypto-examples/
GNU General Public License v2.0
1.64k stars 194 forks source link

how to get output of SHA algorithms as HEX #16

Closed luzfcb closed 8 years ago

luzfcb commented 8 years ago

First, thanks for the great examples. I'm still a novice with javascript. I'm trying to mix FileAPI with webcrypto

I would like to select a file in an input type="file" and get the same hash it would obtain when executing sha1sum via terminal

$ sha1sum LICENSE.txt 
23a1f87d806ce0330b3d85485e399a5f9f553409  LICENSE.txt

My current doubt is how transform ArrayBuffer get HEX in same output HEX format of sha1sum Linux command.

my test code is this:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
</head>
    <body>

        <form action="" enctype="multipart/form-data">
            <p>
                <label for="id_file">File:</label>
                <input id="id_file" name="file_input" type="file">
            </p>

            <p>
                <label for="id_checksum">checksum:</label>
                <input id="id_checksum" maxlength="1000" name="checksum" type="text">
            </p>
        </form>

        <script>
            function arrayBuffer_to_hex(array_b) {
                // what should I do here
                return array_b;
            }

            function handleFileSelect(evt) {
                var files = evt.target.files; // FileList object

                // Loop through the FileList and generate shasum
                for (var i = 0, f; f = files[i]; i++) {

                    // Only process image files.
                    //if (!f.type.match('image.*')) {
                    //    continue;
                    //}

                    var reader = new FileReader();
                    // Closure to capture the file information.
                    reader.onload = (function (theFile) {
                        return function (e) {
                            window.crypto.subtle.digest(
                                    {
                                        name: "SHA-1"
                                    },
                                    e.target.result
                            )
                                    .then(function (hash) {
                                        //
                                        var hex_value = arrayBuffer_to_hex(hash);
                                        console.log(hex_value);
                                        document.getElementById('id_checksum').value = hex_value;

                                    })
                                    .catch(function (err) {
                                        console.error(err);
                                    });
                        };
                    })(f);

                    // Read in the image file as a data URL.
                    reader.readAsArrayBuffer(f);
                }
            }

            document.getElementById('id_file').addEventListener('change', handleFileSelect, false);
        </script>
    </body>
</html>
diafygi commented 8 years ago

You can just loop through the bytes and print them as hex.

function arrayBuffer_to_hex(array_b) {
    var hex_string = "";
    var bytes = new Uint8Array(array_b);
    for(var i = 0; i < bytes.length; i++){
        var hex_i = bytes[i].toString(16);
        hex_string += hex_i.length === 1 ? "0" + hex_i : hex_i;
    }
    return hex_string;
}
luzfcb commented 8 years ago

Thank you for giving of your time to answer this question.

A few minutes before you answer, I found this: https://chromium.googlesource.com/chromium/blink/+/master/LayoutTests/crypto/subtle/resources/common.js#20