Javascript formdata:在追加

时间:2017-02-09 10:28:01

标签: javascript encryption aes form-data

我需要修改涉及将文件上传到服务器的现有前端(角度)代码。现在文件需要在上传之前加密。

当前的方法使用FormData附加大量文件并在单个请求中发送它们,如下所示:

    function uploadFiles(wrappers){

        var data = new FormData();

        // Add each file
        for(var i = 0; i < wrappers.length; i++){

            var wrapper = wrappers[i];
            var file = wrapper.file;
            data.append('file_' + i, file);
        }

        $http.post(uri, data, requestCfg).then(

        /*...*

我一直在其他项目中使用Forge,但从来没有在这种情况下,并没有真正看到如何动态加密文件,仍然将它们作为FormData内容附加。

Forge提供了一个简单的API:

var key = forge.random.getBytesSync(16);
var iv = forge.random.getBytesSync(8);

// encrypt some bytes
var cipher = forge.rc2.createEncryptionCipher(key);
cipher.start(iv);
cipher.update(forge.util.createBuffer(someBytes));
cipher.finish();
var encrypted = cipher.output;

后端使用Formidable接收文件,所有文件hanlding已经连线。因此,我希望坚持使用现有的前端逻辑,而只需插入加密逻辑。在那里,并不是整个formdata都必须加密......我还没有找到一个好的领导来解决这个问题。

建议非常欢迎!

1 个答案:

答案 0 :(得分:0)

好的,找到了解决方案并添加了解密代码。这会添加一层异步代码。

        function appendFile(aFile, idx){

            // Encrypt if a key was provided for this protocol test
            if(!key){
                data.append('dicomfile_' + idx, file);
                appendedCount++;
                onFileAppended();
            }

            else{
                var reader = new FileReader();
                reader.onload = function(){

                    // 1. Read bytes
                    var arrayBuffer = reader.result;
                    var bytes = new Uint8Array(arrayBuffer);    // byte array aka uint8

                    // 2. Encrypt
                    var cipher = forge.cipher.createCipher('AES-CBC', key);
                    cipher.start({iv: iv});
                    cipher.update(forge.util.createBuffer(bytes));
                    cipher.finish();

                    // 3. To blob (file extends blob)
                    var encryptedByteCharacters = cipher.output.getBytes();     // encryptedByteCharacters is similar to an ATOB(b64) output
                    // var asB64 = forge.util.encode64(encryptedBytes); 
                    // var encryptedByteCharacters = atob(asB64);

                    // Convert to Blob object
                    var blob = byteCharsToBlob(encryptedByteCharacters, "application/octet-stream", 512);

                    // 4. Append blob
                    data.append('dicomfile_' + idx, blob, file.name);

                    // Decrypt for the sake of testing
                    if(true){

                        var fileReader = new FileReader();
                        fileReader.onload = function() {
                            arrayBuffer = this.result;
                            var bytez = new Uint8Array(arrayBuffer);
                            var decipher = forge.cipher.createDecipher('AES-CBC', key);
                            decipher.start({iv: iv});
                            decipher.update(forge.util.createBuffer(bytez));
                            decipher.finish();
                            var decryptedByteCharacters = decipher.output.getBytes();
                            var truz = bytes === decryptedByteCharacters;
                            var blob = byteCharsToBlob(decryptedByteCharacters, "application/octet-stream", 512);
                            data.append('decrypted_' + idx, blob, file.name + '.decrypted');

                            appendedCount++;
                            onFileAppended();       
                        };
                        fileReader.readAsArrayBuffer(blob);
                    }

                    else{

                        // z. Resume processing
                        appendedCount++;
                        onFileAppended();                           
                    }
                }

                // Read file
                reader.readAsArrayBuffer(aFile);
            }
        }

function onFileAppended(){

            // Only proceed when all files were appended and optionally encrypted (async) 
            if(appendedCount !== wrappers.length) return;
            /* resume processing, upload or do whathever */