使用CryptoJS进行上载和加密

时间:2014-08-31 15:39:12

标签: filereader cryptojs

这里的目标是上传文件,在客户端对其进行加密,然后通过AJAX将文件及其属性发送到myphpscript.php。为了允许更大的文件,我想使用FileReader切片方法上传切片,并使用CryptoJS网站(https://code.google.com/p/crypto-js/)上描述的方法逐步加密切片。我的代码在下面运行,但最终只会存储预期的整个加密文件的一小部分。我可以按照我描述的方式逐步上传和加密吗?

<script type="text/javascript" src="js/jquery-1.11.0.min.js"></script>
<script src="js/aes.js"></script>
<script>
    function readBlob(opt_startByte, opt_stopByte) {

        var files = document.getElementById('fileinput').files;
        if (!files.length) {
            alert('Please select a file!');
            return;
        }

        var file = files[0];
        var start = parseInt(opt_startByte) || 0;
        var stop = parseInt(opt_stopByte) || file.size - 1;

        var reader = new FileReader();

        // If we use onloadend, we need to check the readyState.
        reader.onloadend = function(evt) {
            if (evt.target.readyState == FileReader.DONE) { // DONE == 2
                window.bits.push(aesEncryptor.process(evt.target.result));
            }
        };

        var blob = file.slice(start, stop + 1);
        reader.readAsBinaryString(blob);
    }

    function handling(evt) {

        // INITIALIZE PROGRESSIVE ENCRYPTION
        var key = CryptoJS.enc.Hex.parse(document.getElementById('pass').value);
        var iv = CryptoJS.lib.WordArray.random(128 / 8);
        window.bits = [];
        window.aesEncryptor = CryptoJS.algo.AES.createEncryptor(key, {iv: iv});

        // LOOP THROUGH BYTES AND PROGRESSIVELY ENCRYPT
        var startByte = 0;
        var endByte = 0;
        while(startByte < document.querySelector('input[type=file]').files[0].size - 1){
            endByte = startByte + 1000000;
            readBlob(startByte, endByte);
            startByte = endByte;
        }

        // FINALIZE ENCRYPTION AND UPLOAD
        var encrypted = aesEncryptor.finalize();
        encrypted = encodeURIComponent(encrypted);
        var filename = document.getElementById('fileinput').value;
        var file_type = document.getElementById('fileinput').files[0].type;
        var url = 'data=' + encrypted + '&filename=' + filename + '&filetype=' + file_type;
        $.ajax({
            url: 'myphpscript.php',
            type: 'POST',
            data: url
        }).success(function(data){
            // Display encrypted data
            document.getElementById('status').innerHTML = 'Upload Complete.';
        });
        alert(encrypted);

    }
</script>

2 个答案:

答案 0 :(得分:0)

所以问题就在于行var encrypted = aesEncryptor.finalize();

这不是加密文件,而是最终的&#39;&#39;由CryptoJS.AES终结器制作。

您需要将其附加到window.bits缓冲区的末尾以生成完全加密的文件。

另外,你不应该使用window.bits.push,你应该像这样保持对每个块的引用(伪代码):

var prog;
//then in the loop, if chunk is null assign to chunk or else concat:
loop:
    if(!prog)
        prog = cipher.process()
    else
        prog.concat(cipher.process())

//then finalize
prog.concat(cipher.finalize())

//now you're free to do whatever with the encrypted file:
var ciphertext = prog.toString()

答案 1 :(得分:0)

要记住的一件重要事情是,块可能无序地到达加密器,因此您要么必须跟踪块进入aesEncryptor.process的顺序,以便您可以稍后以正确的顺序解密对块进行排队,并以正确的顺序加密它们。