CryptoJS对pdf 直传 腾讯云对象存储桶加密和解密
beforeUploadPrice(file) {
console.log('beforeUpload', file)
const isPdf = file.type.startsWith('application/pdf')
const isLt5M = file.size / 1024 / 1024 < 5
if (!isPdf) {
this.$message.error('只能上传pdf文件!')
return false
}
if (!isLt5M) {
this.$message.error('大小不能超过 100MB!')
return false
}
// 生成唯一密钥
const key = CryptoJS.lib.WordArray.random(16).toString(CryptoJS.enc.Hex) // 128-bit key
console.log('Generated Key:', key)
// 读取文件内容
const reader = new FileReader()
reader.onload = (e) => {
const fileData = e.target.result
console.log('fileData:', fileData)
// console.log('fileData type:', typeof fileData)
console.log('fileData byteLength:', fileData.byteLength)
// 将 ArrayBuffer 转换为 WordArray
const wordArray = CryptoJS.lib.WordArray.create(fileData)
// console.log('wordArray:', wordArray)
console.log('wordArray words:', wordArray.words)
console.log('wordArray sigBytes:', wordArray.sigBytes)
// 加密文件
const encrypted = CryptoJS.AES.encrypt(wordArray, key, {
format: CryptoJS.format.OpenSSL
}).toString()
// console.log('encrypted:', encrypted)
console.log('encrypted length:', encrypted.length)
// 生成文件名
const currentYear = new Date().getFullYear()
const currentMonth = String(new Date().getMonth() + 1).padStart(2, '0')
const timestamp = Date.now()
const randomNumber = Math.floor(Math.random() * 10000)
.toString()
.padStart(4, '0')
const fileExtension = '.pdf' // 固定为 pdf 文件
const encryptedFileName = `uploads/${currentYear}/bid/${currentMonth}/${timestamp}${randomNumber}${fileExtension}`
console.log('encryptedFileName:', encryptedFileName)
// 将加密后的文件内容转换为 Blob
const encryptedBlob = new Blob([encrypted], { type: 'application/octet-stream' })
console.log('encryptedBlob:', encryptedBlob)
console.log('encryptedBlob size:', encryptedBlob.size)
// 上传加密后的文件到 COS
this.cosData.key = encryptedFileName
this.uploadPriceFileToCOS(file, encryptedBlob, encryptedFileName, key)
}
reader.readAsArrayBuffer(file)
return false // 阻止默认上传行为
},
// 解密代码
async downloadAndDecryptFile(fileUrl, key, event) {
try {
const config = {
headers: {
...this.cosHeaders,
'Content-Type': 'application/octet-stream'
},
responseType: 'text'
}
console.log('开始下载文件:', fileUrl)
// 下载加密文件
const response = await axios.get(fileUrl, config)
// console.log('response:', response)
const encryptedFileContent = response.data
console.log('encryptedFileContent:', encryptedFileContent)
console.log('encryptedFileContent type:', typeof encryptedFileContent)
console.log('开始解密文件...')
try {
const decrypted = CryptoJS.AES.decrypt(encryptedFileContent, key, {
format: CryptoJS.format.OpenSSL
})
console.log('decrypted:', decrypted)
console.log('decrypted sigBytes:', decrypted.sigBytes)
// 检查解密后的数据是否为空
if (decrypted.sigBytes === 0) {
console.error('解密后的数据为空')
throw new Error('解密后的数据为空')
}
console.log('文件解密成功')
// 将解密后的内容转换为 ArrayBuffer
const decryptedArrayBuffer = new ArrayBuffer(decrypted.sigBytes)
const view = new Uint8Array(decryptedArrayBuffer)
for (let i = 0; i < decrypted.sigBytes; i++) {
view[i] = (decrypted.words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff
}
console.log('解密内容转换为 ArrayBuffer 成功')
// 将 ArrayBuffer 转换为 Blob
const decryptedBlob = new Blob([decryptedArrayBuffer], { type: 'application/pdf' })
console.log('解密内容转换为 Blob 成功')
console.log('decryptedBlob:', decryptedBlob)
console.log('decryptedBlob size:', decryptedBlob.size) // 确保 decryptedBlob 的大小不为 0
// 创建对象 URL
const blobUrl = URL.createObjectURL(decryptedBlob)
// 打开文件
const link = document.createElement('a')
link.href = blobUrl
link.download = 'decrypted_' + event + '_file.pdf' // 你可以根据需要更改文件名
document.body.appendChild(link)
link.click()
document.body.removeChild(link)
// 释放对象 URL
URL.revokeObjectURL(blobUrl)
console.log('文件已成功打开')
} catch (decryptError) {
console.error('解密过程中出错:', decryptError)
throw decryptError
}
} catch (error) {
console.error('下载或解密文件时出错:', error)
if (error.response) {
console.error('服务器响应:', error.response.data)
console.error('状态码:', error.response.status)
console.error('请求头:', error.response.headers)
} else if (error.request) {
console.error('请求对象:', error.request)
if (error.request.status === 0) {
console.error('请求未收到响应,可能是网络问题或 CORS 问题')
}
} else {
console.error('错误信息:', error.message)
}
this.$message.error('下载或解密文件时出错!')
}
},