nodejs large file fragment encryption and decryption

Follow previous Blogs: nodejs inserts content to the specified location of the encrypted file

We need to process large files and real progress, so we need to segment encryption and decryption.

1. Front end segmentation

// Slice upload
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 A slice
  let totalPieces = Math.ceil(_size / bytesPerPiece) // Total number of slices
  if (start < _size) {
    end = start + bytesPerPiece
    if (end >= _size) end = _size // Match the last slice
    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) // Encryption completion report key and file relationship
        }              
        this.$refs.home.fetchData()
        return
      }
    }
  }
},

We slice and use recursion. One success is followed by the next. The main idea is that ks, fileId and so on are special pre-processing of encryption and decryption. We can ignore the acquisition of encryption and decryption related parameters

2. Backend merge

Mainly using fs.appendFile

Encryption and decryption

var AES_conf = {
  key: '54F0853FD5D8D2FD61CE33309B0D0273', // secret key
  iv: 'A19820BCE43576DF', // Offset vector
  padding: 'PKCS7Padding', // Complement value
  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', '')
}

Something that's been merged

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') { // If you want to decrypt, you need to remove the first 40 headers
      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') { // If it is the first segment of encryption, header information needs to be added 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)
  })
}

Posted by boby on Tue, 05 May 2020 10:55:34 -0700