Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/file/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript CryptoJS-解密加密文件_Javascript_File_Encryption_Cryptojs - Fatal编程技术网

Javascript CryptoJS-解密加密文件

Javascript CryptoJS-解密加密文件,javascript,file,encryption,cryptojs,Javascript,File,Encryption,Cryptojs,我正在尝试编写一个应用程序,在浏览器中使用JS对文件进行端到端加密。但是,我似乎无法正确解密所有文件 TL;DR由于加密整个大于1MB的文件是不切实际的,所以我尝试逐块加密它们。这样做之后,我尝试将加密字(由CryptoJS的字数组生成)写入一个blob。至于解密,我读取文件并根据加密区块时生成的映射将其拆分为区块,然后尝试解密。问题是解密结果是0位 我猜我没有在正确解密时读取块。请查看下面关于函数getBlob(将数据写入blob)的代码,以及用于读取块的decryptFile的最后一部分 更

我正在尝试编写一个应用程序,在浏览器中使用JS对文件进行端到端加密。但是,我似乎无法正确解密所有文件

TL;DR由于加密整个大于1MB的文件是不切实际的,所以我尝试逐块加密它们。这样做之后,我尝试将加密字(由
CryptoJS
的字数组生成)写入一个blob。至于解密,我读取文件并根据加密区块时生成的映射将其拆分为区块,然后尝试解密。问题是解密结果是0位

我猜我没有在正确解密时读取块。请查看下面关于函数
getBlob
(将数据写入blob)的代码,以及用于读取块的
decryptFile
的最后一部分

更多解释

我正在使用默认设置的CryptoJS AES

现在,我的代码如下所示:

function encryptFile (file, options, resolve, reject) {
  if (!options.encrypt) {
    return resolve(file)
  }
  if (!options.processor || !options.context) {
    return reject('No encryption method.')
  }

  function encryptBlob (file, optStart, optEnd) {
    const start = optStart || 0
    let stop = optEnd || CHUNK_SIZE
    if (stop > file.size - 1) {
      stop = file.size
    }

    const blob = file.slice(start, stop)
    const fileReader = new FileReader()

    fileReader.onloadend = function () {
      if (this.readyState !== FileReader.DONE) return

      const index = Math.ceil(optStart / CHUNK_SIZE)
      const result = CryptoJS.lib.WordArray.create(this.result)
      encryptedFile[index] = encrypt(result)

      chunksResolved++
      if (chunksResolved === count) {
        const {sigBytes, sigBytesMap, words} = getCipherInfo(encryptedFile)
        const blob = getBlob(sigBytes, words)

        resolve(blob, Object.keys(sigBytesMap))
      }
    }
    fileReader.readAsArrayBuffer(blob)
  }

  let chunksResolved = 0
  const encryptedFile = []
  const CHUNK_SIZE = 1024*1024
  const count = Math.ceil(file.size / CHUNK_SIZE)
  const encrypt = value => options.processor.call(
    options.context, value, 'file',
    (v, k) => CryptoJS.AES.encrypt(v, k))

  for (let start = 0; (start + CHUNK_SIZE) / CHUNK_SIZE <= count; start+= CHUNK_SIZE) {
    encryptBlob(file, start, start + CHUNK_SIZE - 1)
  }
}
解密与加密完全相同,但不起作用。虽然块不再是1MB,但它们仅限于图中提到的sigBytes。解密没有结果<代码>字节:0

以下是生成blob和获取sigbytesMap的代码:

function getCipherInfo (ciphers) {
  const sigBytesMap = []
  const sigBytes = ciphers.reduce((tmp, cipher) => {
    tmp += cipher.sigBytes || cipher.ciphertext.sigBytes
    sigBytesMap.push(tmp)
    return tmp
  }, 0)

  const words = ciphers.reduce((tmp, cipher) => {
    return tmp.concat(cipher.words || cipher.ciphertext.words)
  }, [])

  return {sigBytes, sigBytesMap, words}
}

function getBlob (sigBytes, words) {
  const bytes = new Uint8Array(sigBytes)
  for (var i = 0; i < sigBytes; i++) {
    const byte = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff
    bytes[i] = byte
  }

  return new Blob([ new Uint8Array(bytes) ])
}
函数getCipherInfo(密码){ 常量sigBytesMap=[] const sigBytes=密码。reduce((tmp,cipher)=>{ tmp+=cipher.sigBytes | | cipher.ciphertext.sigBytes sigBytesMap.push(tmp) 返回tmp }, 0) const words=密码。reduce((tmp,密码)=>{ 返回tmp.concat(cipher.words | | cipher.ciphertext.words) }, []) 返回{sigBytes,sigBytesMap,words} } 函数getBlob(sigBytes,words){ 常量字节=新的Uint8Array(sigBytes) 对于(变量i=0;i>>2]>>(24-(i%4)*8))&0xff 字节[i]=字节 } 返回新Blob([新Uint8Array(字节)]) } 我猜问题在于我用来读取加密块的方法。或者写下来


我还应该提到,以前我做了一些不同的加密。我使用默认编码(我相信是
CryptoJS.enc.Hex
)的
toString
方法对作为
CryptoJS.AES.encrypt
结果得到的每个字数组进行了字符串化,但有些文件没有正确解密。它与原始文件的大小无关,而与它们的类型无关。再说一遍,我猜

原来问题在于
CryptoJS.AES返回的
WordArray
。decrypt(value,key)
有4个额外的单词作为填充,不应包含在最终结果中。CryptoJS尝试添加结果,但只会相应地更改
sigBytes
,而不会更改
单词。因此,在解密时,在将块写入文件之前,请弹出这些额外的单词。4个单词代表完整的块,3个单词代表较小的块(最后一块)。

1)你为什么这样做?2) 你知道那是不安全的吗?使用这种加密技术,您到底实现了什么?由于它是浏览器到浏览器-密钥将是可见的,那么重点是什么?是
k
硬编码还是通过非对称加密检索?@Mjh实现零知识加密,因此我们将无法访问用户的数据。如果你有密钥,你就有了关于数据的知识。既然你有钥匙,这个零知识原则就被打破了。SSL/TLS有什么问题?对,你用什么加密数据?用户的公钥?公钥加密对可以加密的数据量有限制。你的系统的整个前提听起来完全不正确——你有一个可以看到其内容的文件。如果看不到内容,就不需要加密。您只需将损坏的blob传递给另一个人,他将通过向所有者询问密钥来解密它。你在这里有太多的错误决定,如果我知道你提供的是哪种服务,我永远不会注册。没有怨恨,这里有太多的“错误”。
function getCipherInfo (ciphers) {
  const sigBytesMap = []
  const sigBytes = ciphers.reduce((tmp, cipher) => {
    tmp += cipher.sigBytes || cipher.ciphertext.sigBytes
    sigBytesMap.push(tmp)
    return tmp
  }, 0)

  const words = ciphers.reduce((tmp, cipher) => {
    return tmp.concat(cipher.words || cipher.ciphertext.words)
  }, [])

  return {sigBytes, sigBytesMap, words}
}

function getBlob (sigBytes, words) {
  const bytes = new Uint8Array(sigBytes)
  for (var i = 0; i < sigBytes; i++) {
    const byte = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff
    bytes[i] = byte
  }

  return new Blob([ new Uint8Array(bytes) ])
}