zoukankan      html  css  js  c++  java
  • nodejs大文件分片加密解密

      承接之前博客:nodejs向加密文件指定位置插入内容

      我们需要对大文件进行处理,并需要真实的进度,那么就需要分片加密和解密。

    1、前端分片

    // 分片上传
    async burst (ks, cryType, id) {
      let _home = this.$refs.home
      let successNum = 0
      let index = 0
      let start = 0
      let end = 0
      this.burstOneByOne(_home, successNum, index, start, end, ks, cryType, id)
    },
    async burstOneByOne (_home, successNum, index, start, end, ks, cryType, id) {
      let _size = _home.curSize
      let bytesPerPiece = 1024 * 1024 * 3 // 3M一个分片
      let totalPieces = Math.ceil(_size / bytesPerPiece) // 切片总数
      if (start < _size) {
        end = start + bytesPerPiece
        if (end >= _size) end = _size // 匹配最后一个分片的情况
        let _params = {
          start: start,
          end: end,
          index: index,
          filepath: _home.curPath,
          filename: _home.curFile,
          ks: ks,
          cryType: cryType
        }
        if (id) {
          _params.fileId = id
        }
        let res = await burstFileApi(_params)
        if (res.status) {
          successNum++
          this.percentage = (100 * successNum / totalPieces).toFixed(2) - 0
          start = end
          index++
          if (index < totalPieces) {
            this.burstOneByOne(_home, successNum, index, start, end, ks, cryType, id)
          } else {
            if (id) {
              this.submitFileKdRelation(id) // 加密完成上报密钥与文件关系
            }              
            this.$refs.home.fetchData()
            return
          }
        }
      }
    },

      我们分片并使用递归,一个成功才接着下一个,主要是思路,ks、fileId等很多是特殊的加密解密前处理,获取加解密相关参数的东西,可以不理会

    2、后端合并

      主要使用fs.appendFile的方法

      加解密的东西

    var AES_conf = {
      key: '54F0853FD5D8D2FD61CE33309B0D0273', // 密钥
      iv: 'A19820BCE43576DF', // 偏移向量
      padding: 'PKCS7Padding', // 补全值
      code: 'JeOW0ix7'
    }
    function aesEncryptNew (buff, key, iv) {
      let cipher = crypto.createCipheriv('aes-256-cbc', key, iv)
      let crypted = cipher.update(buff, '', 'hex')
      crypted += cipher.final('hex')
      return crypted
    }
    function aesDecryptNew (buff, key, iv) {
      let decipher = crypto.createDecipheriv('aes-256-cbc', key, iv)
      return decipher.update(buff, 'hex', '')
    }

      文件合并的东西

    function burstFile (query) {
      return new Promise((resolve, reject) => {
        let { start, end, filepath, filename, index, ks, cryType, fileId } = query
        let _path = path.join(filepath, filename)
        let buff = fs.readFileSync(_path)
        if (cryType === 'decry') { // 如果解密的话需要剔除掉前面的40个头信息
          buff = buff.slice(40)
        }
        let bufferFile = buff.slice(start, end)
        encryptBurstFile(bufferFile, _path, ks, cryType, index, fileId).then(_ => {
          resolve()
        }).catch(err => {
          console.log('err', err)
          reject(err)
        })
      })
    }
    function encryptBurstFile (buff, _path, ks, cryType, index, fileId) {
      return new Promise(function (resolve, reject) {
        let key = AES_conf.key
        if (ks) {
          key = ks
        }
        let iv = AES_conf.iv
        let buffEnc = cryType === 'encry' ? aesEncryptNew(buff, key, iv) : aesDecryptNew(buff, key, iv)
        let _newPath = ''
        if (cryType === 'encry') {
          _newPath = _path + '.mc.bin'
          if (index === '0') { // 如果是加密的第一个分片,需要加上头信息code
            let code = AES_conf.code + fileId
            fs.appendFileSync(_newPath, code, 'utf8')
          }
          fs.appendFileSync(_newPath, Buffer.from(buffEnc, 'hex'))
        } else {
          _newPath = _path.replace(/.mc.bin/g, '')
          fs.appendFileSync(_newPath, buffEnc)
        }
        resolve(_newPath)
      })
    }
  • 相关阅读:
    php面试题目
    JavaScript表单处理的返回值问题
    超链接在javascript:void(0)时没有事件响应
    php 两个美元符号:可变变量
    [Ubuntu] lampp安装Zend Framework
    [Ubuntu] 安装字体
    php中bindValue 和 bindParam 的区别
    php遍历文件夹(获得文件名)
    php输出一段字符块
    PHP 全角和半角转换函数
  • 原文地址:https://www.cnblogs.com/goloving/p/12827205.html
Copyright © 2011-2022 走看看