簡體   English   中英

如何使用偽造加密和解密pdf blob並存儲在localStorage中?

[英]How can i encrypt and decrypt a pdf blob with forge and store in localStorage?

我試圖加密一個blof的pdf文件並將其存儲在localStorage中,並在我離線時讀取並解密它。

我的應用程序是用AngularJS編寫的,加密是用偽造完成的

這是我下載pdf文件的代碼:

 $http.get(url, { headers: { "Application-Authorization": appContext.user.token }, responseType: "blob" }).then(function(response) { backendCipherService.encryptPDF(response.data, appContext.user.password).then(function(data) { $localForage.setItem("document::" + document.documentId + "::pdf", data.json).then(function(success) { console.log("cached pdf", document.documentId); deferred.resolve(); }, function(error) { console.log("Error", response.data, document.documentName); deferred.reject(error); }); }); }, function(error) { deferred.reject(error); }); 

這是我的加密和解密代碼(backendCipherService):

 this.encryptPDF = function(blob, password) { var salt = forge.random.getBytesSync(256); var key = forge.pkcs5.pbkdf2(password, salt, 40, 32); var iv = forge.random.getBytesSync(32); var cipher = forge.cipher.createCipher('AES-CBC', key); cipher.start({iv: iv}); var deferred = $q.defer(); var uint8Array = null; var arrayBuffer = null; var fileReader = new FileReader(); fileReader.onload = function(progressEvent) { arrayBuffer = this.result; uint8Array = new Uint8Array(arrayBuffer); }; fileReader.readAsArrayBuffer(blob); fileReader.onloadend = function() { var inp = uint8Array; console.log(inp); cipher.update(forge.util.createBuffer(inp)); cipher.finish(); var encrypted = cipher.output; var data = forge.util.bytesToHex(encrypted); var obj = {"salt": forge.util.bytesToHex(salt), "iv": forge.util.bytesToHex(iv), "encrypted": data}; deferred.resolve({ json: angular.toJson(obj) }); }; return deferred.promise; }; this.decryptPDF = function(json, password) { var obj = angular.fromJson(json); var key = forge.pkcs5.pbkdf2(password, forge.util.hexToBytes(obj.salt), 40, 32); var iv = forge.util.createBuffer(); var data = forge.util.createBuffer(); iv.putBytes(forge.util.hexToBytes(obj.iv)); data.putBytes(forge.util.hexToBytes(obj.encrypted)); var decipher = forge.cipher.createDecipher('AES-CBC', key); decipher.start({iv: iv}); decipher.update(data); decipher.finish(); return decipher.output.data; }; 

這是用於將解密值再次轉換為Blob的代碼:

 return $localForage.getItem("document::" + documentId + "::pdf").then(function(pdf) { var pdfBlob = new Blob([backendCipherService.decryptPDF(pdf, appContext.user.password)], {type: 'application/pdf'}); return pdfBlob; }, function(error) { return error; }); 

這通常有效,但pdf無法從PDF.js讀取,我得到錯誤:

 Error: Bad FCHECK in flate stream: 120, 194 pdf.worker.js:252 at error (http://localhost:8080/client/components/pdfjs-dist/build/pdf.worker.js:252:15) at Object.FlateStream (http://localhost:8080/client/components/pdfjs-dist/build/pdf.worker.js:31394:7) at Object.Parser_makeFilter [as makeFilter] (http://localhost:8080/client/components/pdfjs-dist/build/pdf.worker.js:30281:18) at Object.Parser_filter [as filter] (http://localhost:8080/client/components/pdfjs-dist/build/pdf.worker.js:30259:25) at Object.Parser_makeStream [as makeStream] (http://localhost:8080/client/components/pdfjs-dist/build/pdf.worker.js:30234:21) at Object.Parser_getObj [as getObj] (http://localhost:8080/client/components/pdfjs-dist/build/pdf.worker.js:30022:28) at Object.XRef_fetchUncompressed [as fetchUncompressed] (http://localhost:8080/client/components/pdfjs-dist/build/pdf.worker.js:4323:28) at Object.XRef_fetch [as fetch] (http://localhost:8080/client/components/pdfjs-dist/build/pdf.worker.js:4280:26) at Object.XRef_fetchIfRef [as fetchIfRef] (http://localhost:8080/client/components/pdfjs-dist/build/pdf.worker.js:4261:19) pdf.worker.js:235 Warning: Unsupported feature "unknown" pdf.worker.js:235 Warning: Invalid stream: "Error: Bad FCHECK in flate stream: 120, 194" pdf.js:235 Warning: Unsupported feature "unknown" 

似乎pdf以某種方式被破壞了。

有什么想法有什么不對嗎? 謝謝

你的decryptPDF函數返回一個二進制編碼的字符串,這是for v0.6.x的原生格式。 要將其轉換回Uint8Array,請執行以下操作:

decipher.finish();
return s2a(decipher.output.getBytes());

function s2a(str) {
    var view = new Uint8Array(str.length);
    for (var i = 0, j = str.length; i < j; i++) {
        view[i] = str.charCodeAt(i);
    }
    return view;
}

您還應該檢查decipher.finish()的返回值以確保它為true 否則,解密可能已失敗。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM