如何使用forge加密和解密pdf blob并存储在localStorage中
How can i encrypt and decrypt a pdf blob with forge and store in localStorage?
我试图加密一个pdf文件的Blob并将其存储在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似乎不知怎么被破坏了。
有什么想法吗?Thx
您的decryptPDF
函数返回一个二进制编码的字符串,这是forge 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
。否则,解密可能会失败。
相关文章:
- 在特定条件下从存储在localStorage中的阵列中删除对象
- 通过phonegap中的电子邮件发送存储在html5 localStorage中的信息
- 如何在javascript中使用localStorage从数组中存储和提取数据
- 使用localStorage存储号码
- 使用localStorage在本地存储字体
- 如何使用forge加密和解密pdf blob并存储在localStorage中
- JavaScript $http.get 一个 json 数组并将其存储在 localstorage 中
- 估计存储在 localStorage (Javascript) 中的 10,000 个字符字符串的大小
- 使用 localStorage 存储值
- 更好地设计使用 HTML5 localStorage 存储的数据
- 删除 localStorage,Chrome/Chromium 中选项卡的数据库存储
- 如何在 Firefox 附加 SDK 扩展中使用 'jpm run' 时将数据持久存储在 'localStorage'
- 如何在 localStorage 中存储数组
- 使用 localStorage 存储和检索 PNG 时出现空白图像
- 使用localstorage存储表数据并将其传递给窗体
- localStorage未存储预先准备好的注释
- 将php多维数组存储在localstorage中
- 单击时在localStorage中存储多个值
- 正在尝试将对象存储在localStorage中
- 类似localStorage的HTA存储替代方案