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