【发布时间】:2011-11-30 14:06:11
【问题描述】:
我正在尝试构建一种方法来加密文件客户端并上传它。目标是将加密的文件存储在服务器上,只有最终用户才能解密文件。这个问题有点像asked before,但我认为我取得了一些进步。
我的计划是使用新的 Javascript File API 来操作文件并上传。可以使用Stanford Javascript Crypto Library 进行加密。该文件应该以块的形式读取,因此它不会完全读入内存。然后每个块都由 crypt 库加密。我不知道如何实现这一点。作为开始,我有这个:
var fd = new FormData();
var file = document.getElementById('file').files[0];
fd.append("file", file);
var xhr = new XMLHttpRequest();
xhr.open("POST", "/upload/");
xhr.send(fd);
这只是常规的 javascript 上传。我正在尝试构建一个模仿 File 对象行为的 Crypt 对象并将其传递给 FormData。对于 formdata 读取的每个数据块,对象应该从文件中读取一个块并对其进行加密。我只是无法弄清楚 FormData 如何处理 File 对象以及是否可以复制此行为。我不确定这是否是正确的做法,有人有建议吗?
更新:好的,我现在更进一步了。我正在使用 file.slice 分块读取文件。然后使用 BlobBuilder 对每个块进行加密并转换回 blob。然后将此 blob 放入 FormData 对象并提交给服务器。服务器将连接这些 blob。使用浏览器加密和解密一个块是有效的。现在我正在下载和解密多个块。
还有一些问题需要解决:
- 文件名丢失,尚无法为文件对象设置 FileName。
- 加密仍然阻塞(没有 ui 更新),但我想我可以通过 webworkers 解决这个问题。
- 下载时我无法预测块大小。未加密的块大小是已知的,但对于加密数据,这似乎有所不同。此加密数据以 JSON 形式存储,我不希望对 } 进行字符串搜索。而且我不想存储这个服务器端。
- 虽然我正在读取分块文件,但 Firefox 似乎存在内存泄漏或将完整文件读入内存。这会成为数 GB 文件的问题。
【问题讨论】:
-
你想保护它免受谁的侵害?为什么不直接使用 https?
-
@Spudley 当然,这取决于您是否要在客户端加密文件以确保服务器端无法访问原始内容,而不是需要这样的解决方案。 HTTPS 只会阻止中间人获得访问权限。
-
@Spudley:确切地说,这样文件就可以保护所有人,甚至是服务器维护者或黑客。
-
如果有人入侵了服务器,他们可以修改 JS 代码来获取密钥。此外,如果您不使用 HTTPS,那么中间人也可以这样做。然而,加密确实使黑客攻击服务器的人更难解密在黑客攻击发生之前上传的文件。但在这种情况下,加密是在客户端还是在服务器端进行的没有区别。
-
数据应加密存储。我们不想通过网络发送未加密的数据或密钥。是的,我们将使用 HTTPS。但是让加密发生在服务器端意味着服务器需要密钥。服务器永远不应该访问密钥。数据的存储最终可能由第 3 方或“在云中”的某个地方完成。我们希望加密发生在尽可能靠近用户的地方。
标签: javascript encryption file-upload