承接之前博客: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) }) }