我怎样才能加密和解密PDF一滴在localStorage的锻造和存储? [英] How can i encrypt and decrypt a pdf blob with forge and store in localStorage?

查看:1992
本文介绍了我怎样才能加密和解密PDF一滴在localStorage的锻造和存储?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图加密PDF文件的Blob和其存储在localStorage的阅读并解密后,当我是脱机。

我的应用程序是写在AngularJS和加密与锐意

下面是我的code下载PDF文件:

\r
\r

$ http.get(URL,{\r
                    标题:{\r
                        应用程序授权:appContext.user.token\r
                    },\r
                    的responseType:斑点\r
                })。然后(功能(响应){\r
\r
                    backendCipherService.encryptPDF(response.data,appContext.user.password)。然后(功能(数据){\r
                        $ localForage.setItem(文件::+ document.documentId +:: PDF,data.json)。然后(函数(成功){\r
                            的console.log(缓存PDF,document.documentId);\r
                            deferred.resolve();\r
                        },功能(错误){\r
                            的console.log(错误,response.data,document.documentName);\r
                            deferred.reject(错误);\r
                        });\r
                    });\r
                },功能(错误){\r
                    deferred.reject(错误);\r
                });

\r

\r
\r

和这里是我的code用于加密和解密(backendCipherService):

\r
\r

this.encryptPDF =功能(BLOB,密码){\r
            变种盐= forge.random.getBytesSync(256);\r
            VAR键= forge.pkcs5.pbkdf2(口令,盐,40,32);\r
            变种IV = forge.random.getBytesSync(32);\r
            VAR密码= forge.cipher.createCipher(AES-CBC,键);\r
\r
            cipher.start({四:四});\r
            变种推迟= $ q.defer();\r
\r
            VAR uint8Array = NULL;\r
            VAR arrayBuffer = NULL;\r
            VAR的FileReader =新的FileReader();\r
            fileReader.onload =功能(progressEvent){\r
                arrayBuffer = this.result;\r
                uint8Array =新Uint8Array(arrayBuffer);\r
            };\r
            fileReader.readAsArrayBuffer(BLOB);\r
            fileReader.onloadend =功能(){\r
                VAR INP = uint8Array;\r
                的console.log(INP);\r
                cipher.u​​pdate(forge.util.createBuffer(INP));\r
                cipher.finish();\r
                VAR加密= cipher.output;\r
                VAR数据= forge.util.bytesToHex(加密);\r
                变种物镜= {盐:forge.util.bytesToHex(盐),四:forge.util.bytesToHex(iv)中,加密的:数据};\r
                deferred.resolve({\r
                    JSON:angular.toJson(OBJ)\r
                });\r
            };\r
            返回deferred.promise;\r
        };\r
\r
        this.decryptPDF =函数(JSON,密码){\r
            VAR OBJ = angular.fromJson(JSON);\r
            VAR键= forge.pkcs5.pbkdf2(密码,forge.util.hexToBytes(obj.salt),40,32);\r
            变种IV = forge.util.createBuffer();\r
            VAR数据= forge.util.createBuffer();\r
            iv.putBytes(forge.util.hexToBytes(obj.iv));\r
            data.putBytes(forge.util.hexToBytes(obj.encrypted));\r
\r
            VAR译码= forge.cipher.createDecipher(AES-CBC,键);\r
            decipher.start({四:四});\r
            decipher.u​​pdate(数据);\r
            decipher.finish();\r
            返回decipher.output.data;\r
        };

\r

\r
\r

和这里是code再次转换解密值的Blob:

\r
\r

收益$ localForage.getItem(文件::+ documentId +:: PDF格式)。然后(函数(pdf){\r
                VAR pdfBlob =新的Blob([backendCipherService.decryptPDF(PDF,appContext.user.password)] {类型:应用程序/ PDF'});\r
                返回pdfBlob;\r
            },功能(错误){\r
                返回错误;\r
            });

\r

\r
\r

这一般的作品,但PDF不能从PDF.js阅读,我得到的错误:

\r
\r

错误:flate流坏FCHECK:120,194\r
pdf.worker.js:252错误(http://本地主机:8080 /客户端/组件/ pdfjs - 距离/编译/ pdf.worker.js:252:15)\r
    在Object.FlateStream(HTTP://本地主机:8080 /客户端/组件/ pdfjs - 距离/编译/ pdf.worker.js:31394:7)\r
    在Object.Parser_makeFilter [如makeFilter(HTTP://本地主机:8080 /客户端/组件/ pdfjs - 距离/编译/ pdf.worker.js:30281:18)\r
    在Object.Parser_filter [作为过滤(HTTP://本地主机:8080 /客户端/组件/ pdfjs - 距离/编译/ pdf.worker.js:30259:25)\r
    在Object.Parser_makeStream [如makeStream(HTTP://本地主机:8080 /客户端/组件/ pdfjs - 距离/编译/ pdf.worker.js:30234:21)\r
    在Object.Parser_getObj [如getObj(HTTP://本地主机:8080 /客户端/组件/ pdfjs - 距离/编译/ pdf.worker.js:30022:28)\r
    在Object.XRef_fetchUncom pressed [如fetchUncom pressed(HTTP://本地主机:8080 /客户端/组件/ pdfjs - 距离/编译/ pdf.worker.js:4323:28)\r
    在Object.XRef_fetch [如取(HTTP://本地主机:8080 /客户端/组件/ pdfjs - 距离/编译/ pdf.worker.js:4280:26)\r
    在Object.XRef_fetchIfRef [如fetchIfRef(HTTP://本地主机:8080 /客户端/组件/ pdfjs - 距离/编译/ pdf.worker.js:4261:19)\r
pdf.worker.js:235警告:不支持的功能未知\r
pdf.worker.js:235警告:无效的流:错误:flate流坏FCHECK:120,194\r
pdf.js:235警告:不支持的功能未知

\r

\r
\r

看来,PDF是莫名其妙地损坏。

任何想法有什么不对?
THX


解决方案

decryptPDF 函数返回一个二进制恩codeD字符串,它是原生格式锐意v0.6.x与工作。要转换回Uint8Array做到这一点,而不是:

  decipher.finish();
返回S2A(decipher.output.getBytes());功能S2A(STR){
    VAR视图=新Uint8Array(str.length);
    对于(VAR I = 0,J = str.length; I<焦耳;我++){
        鉴于[I] = str.char $ C $猫(I)
    }
    返回视图。
}

您也应该检查 decipher.finish()的返回值,以确保它是真正。否则,解密可能已经失败。

I've trying to encrypt a Blob of pdf file and store it in the localStorage and read and decrypt it later when i'm offline.

My app is written in AngularJS and the encryption is done with forge

Here is my code for downloading the pdf file:

$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);
                });

and here is my code for encryption and decryption (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;
        };

and here is the code for converting the decrypted value to a Blob again:

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;
            });

This in general works but the pdf can not be read from PDF.js and i get the error:

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"

It seems that the pdf is corrupted somehow.

Any ideas what's wrong? Thx

解决方案

Your decryptPDF function is returning a binary-encoded string, which is the native format forge v0.6.x works with. To convert that back to a Uint8Array do this instead:

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;
}

You should also check the return value of decipher.finish() to ensure it is true. Otherwise, the decryption may have failed.

这篇关于我怎样才能加密和解密PDF一滴在localStorage的锻造和存储?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆