【问题标题】:Progressive Upload and Encryption with CryptoJS使用 CryptoJS 进行渐进式上传和加密
【发布时间】:2014-08-31 15:39:12
【问题描述】:

这里的目标是上传文件,在客户端对其进行加密,然后通过 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>

【问题讨论】:

  • 如果您想分几块上传数据,那么我希望看到您在某种循环中发出请求……但我不认为会发生这种情况?
  • 现在我这样做的方式,如果我错了,请纠正我,在评论“循环字节并逐步加密”的部分中。在那个 while 循环中,我运行读取特定切片的函数 readBlob。
  • 但是你在那个循环之外发送数据到你的服务器,然后……
  • 我明白你的意思;澄清一下,我不一定要分块上传数据,我想从 FileReader 逐步加密其切片,然后一次上传。也许一次上传会破坏渐进式切片和加密的目的,如果是这样,另一种方法会有所帮助:)

标签: filereader cryptojs


【解决方案1】:

所以你的问题是var encrypted = aesEncryptor.finalize();这一行

这不是加密文件,而是 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()

【讨论】:

    【解决方案2】:

    要记住的重要一点是,块可能会乱序到达加密器,因此您要么必须跟踪块进入 aesEncryptor.process 的顺序,以便您可以稍后以正确的顺序解密将块排队并以正确的顺序加密它们开始。

    【讨论】:

    • 是的,我详细说明了如何做到这一点here
    猜你喜欢
    • 2022-10-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多