客户端(javascript)文件上传加密

Client side (javascript) file upload encryption

本文关键字:加密 文件 javascript 客户端      更新时间:2023-09-26

我正在尝试构建一种加密文件客户端并上传它的方法。目标是将加密的文件存储在服务器上,并且只有最终用户能够解密该文件。这个问题以前有人问过,但我想我取得了一些进步。

我的计划是使用新的Javascript文件API来操作文件并上传它。加密可以用斯坦福Javascript加密库完成。文件应该以块的形式读取,这样就不会完全读到内存中。然后,每个块都由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上传。我试图建立一个Crypt对象,模仿文件对象的行为,并将其传递给FormData。对于formdata读取的每个数据块,对象应该从文件中读取一个块并对其进行加密。我只是无法弄清楚FormData是如何处理文件对象的,如果有可能复制这种行为。我不确定这是不是正确的做法,有人有什么建议吗?

UPDATE:好了,我现在走得更远了。我用的是file。Slice以块的形式读取文件。然后使用BlobBuilder对每个块进行加密并转换回blob。然后将该blob放入FormData对象并提交给服务器。服务器将连接这些blob。用浏览器加密和解密一个块正在工作。现在我正在下载和解密多个块。

还有一些问题需要解决:

  • 文件的名称丢失了,还不能为文件对象设置FileName。
  • 加密仍然阻塞(没有ui更新),但我想我可以解决这个与网络工作者。
  • 下载时我无法预测块大小。未加密的块大小是已知的,但对于加密的数据,这似乎有所不同。这个加密的数据以JSON形式存储,我不喜欢对}进行字符串搜索。我不喜欢存储这个服务器端。
  • 虽然我正在读取文件块,Firefox似乎有内存泄漏或读取完整的文件到内存。这对于多gb的文件来说是一个问题。

以下是一个强保护文件的解决方案。

职业:

  • 攻击者可以访问服务器,但无法使用数据。
  • 即使您(开发人员)也无法访问数据。

缺点:

  • 如果用户密码丢失,数据也会丢失。
  • 即使你(开发人员)也不能访问数据(这意味着如果用户遇到任何问题,你不能帮助用户)。

如果这是你需要的,那就去做^^。注意:以下所有操作都发生在服务器端。

  1. 使用https传输
  2. 当用户登录时,创建用户密码的哈希值(例如sha(password + salt))
  3. 在用户会话中存储哈希
  4. 上传完成后,使用对称加密(例如AES)以会话中存储的哈希值作为密钥对数据进行加密。
  5. 下载完成后,使用相同的对称解密方法解密文件并将其发送回用户。

这意味着只有已登录的用户才能以普通方式访问数据。并且只有数据所属的用户。访问用户数据的唯一可能性是知道他的密码。

注意:如果上传文件的用户和读取文件的用户不是同一个人,你可以使用非对称和对称加密的组合:

  1. 为接收方生成公钥/私钥对。
  2. (对称)用接收方的哈希值或a加密私钥依赖的他的密码。
  3. 上传文件时,使用接收方的非对称加密罢工公钥。

  4. (新)非对称加密似乎比对称加密慢得多(10-100倍,取决于算法/架构)。因此,最好生成一个随机数(会话密钥),对其进行两次非对称加密(一次使用发送方的公钥,一次使用接收方的公钥)并存储它们。然后使用对称加密对文件进行加密(使用明文会话密钥作为对称密钥)

  5. 当收件人想要访问文件时:

    a)用他的哈希值或密码依赖来解密他的私钥。

    b) 使用私钥解密文件

    b) (new)使用私钥解密接收方加密的会话密钥。然后使用对称解密对文件进行解密