如何使用 forge 加密和解密 pdf blob 并将其存储在 localStorage 中?

2023-11-30

我试图加密一个 pdf 文件 Blob 并将其存储在 localStorage 中,并在离线时读取和解密它。

我的应用程序是用 AngularJS 编写的,加密是用forge

这是我下载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.js 读取 pdf,并且出现错误:

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 似乎已损坏。

任何想法有什么问题吗? 谢谢


Your 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。否则,解密可能会失败。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用 forge 加密和解密 pdf blob 并将其存储在 localStorage 中? 的相关文章

  • 如何动态删除嵌套的json键?

    这是示例 json search facets author language value nep count 3 value urd count 1 source value West Bengal State Council of Vo
  • 玉石压痕错误

    因此 对于我的 Express 网站 我使用 jade 所以我决定尝试修改我的布局文件 以便我可以开始设计我的网站 我修改了原始布局代码 有效 但我开始在任何扩展布局的文件中出现缩进错误 如下所示 500 Error home kevin
  • 如何在角度通用中使用localStorage?

    我正在使用 angular v4 0 3 和 webpack 2 2 0 使用它工作得很好Auler http ium com evertonrobertoauler angular 4 universal app with angular
  • 鼠标移动时画布拖动

    我正在尝试构建一个可以使用鼠标移动拖动的画布 我做了一些我无法理解的错误 因为一开始似乎有效 然后出现了一个增量错误 使画布移动得太快 考虑以下代码 window onload function var canvas document ge
  • 使用 babel env 预设时,展开运算符出现语法错误

    我正在努力 现代化 meern io 入门样板 https github com Hashnode mern starter通过替换巴别塔es2015 and stage 0预设为env 然而 似乎env预设无法识别以下片段client m
  • 让 prerender.io 与 Facebook 爬虫(maven、GAE)一起使用?

    我有一个 angularjs 应用程序 我想在 Facebook 上分享页面 这是通过元标签处理的 https developers facebook com docs sharing best practices https develo
  • 在动态创建的元素的onclick函数的属性中传递一个字符串

    我试图在动态创建的锚元素的 onClick 事件处理函数的参数中传递一个字符串 请参阅小提琴http jsfiddle net shmdhussain bXYe4 http jsfiddle net shmdhussain bXYe4 我无
  • 仅从功能区打开一个对话框

    我有一个带有登录按钮的功能区 可打开登录对话框 我想将对话框的数量限制为一个 我正在使用函数 displayDialogAsync startAddress options callback https learn microsoft co
  • 修复 Raphaël 路径节点上 Tipsy 工具提示的位置

    这是一个非常具体且有些复杂的问题 所以我设置了一个最小测试用例 http reveal dk 8080 revealit dk tipsytest 在阅读本文的其余部分之前 您可能应该先了解一下 我的页面显示悬停时突出显示区域的图像Raph
  • 如何将 PHP 与 yeoman Angular 项目集成

    我在用着yeoman questions tagged yeoman项目使用角js questions tagged angularjs通常我知道如何在普通项目中将 angularjs 与 PHP 结合使用 但我很困惑如何将 php 与 y
  • NodeJS - 将相对路径转换为绝对路径

    In my 文件系统我的工作目录在这里 C temp a b c d 在 b bb 下有文件 tmp txt C temp a b bb tmp txt 如果我想从工作目录转到该文件 我将使用以下路径 bb tmp txt 如果该文件不存在
  • 如何将React JS状态保存到本地存储中

    我不知道如何将 React js 状态存储到本地存储中 import React Component from react import App css import auth createUserProfileDocument from
  • 基于范围内变量的角度设置形式动作

    我一直在尝试设置一个搜索表单 可以在其中注入表单操作属性 在我的表格中我有
  • 为什么 TypeScript 混合了模块和原型模式?

    我正在查看此页面上 TypeScript 生成的 JS 代码 http www typescriptlang org Playground http www typescriptlang org Playground 基本上 要创建一个Gr
  • 如何禁用网页中的萤火虫?

    如何使用 Javascript 禁用 firebug 我想这样做是为了向访问者隐藏我的网页的运作方式 有什么选择可以做到这一点吗 你不能 你能做的最好的事情就是混淆你的 JavaScript 实际上刮掉了 您能做的最好的事情就是将所有安全关
  • 如何计算一行中Flexbox项目的数量?

    网格是使用 CSS flexbox 实现的 Example http jsbin com jumosicasi edit html css js output 本示例中的行数为 4 因为我出于演示目的固定了容器宽度 但是 实际上 它可以根据
  • 使用严格模式编译指示时如何声明全局变量

    使用自调用函数来包装严格模式兼容代码 通常称为严格模式编译指示 被认为是一种很好的做法 function use strict Strict code here 我的问题是在这种情况下如何声明全局变量 我今天知道的三种替代方案 替代方案 1
  • 如何强制下载图片?

    我的页面上有一个动态生成的图像 如下所示 img src 我不想告诉我的用户右键单击图像并点击保存 而是想公开一个下载链接 单击该链接将提示下载图像 如何实现这一目标 最初我在 js 中尝试这样做 var path my image att
  • UI Router 将 url 与 hash(片段)相匹配

    使用 UI 路由器 我需要将 URL 与其中包含的哈希 片段 进行匹配 HTML5 模式 state myState url path id page section templateUrl template html controller
  • 突出显示单词并提取其附近文本的函数

    我有一个文本例如 Etiam porta semmalesuada magna mollis euismod 整数取数 ante venenatis dapibus posuere velit aliquet 埃蒂亚姆 门塔 塞姆 male

随机推荐

  • OpenCV 3.0 VideoCapture 无法在 Java 中打开视频文件

    OpenCV 3 0 with Java无法打开视频文件 但可以使用摄像头 在我使用 OpenCV 3 0 beta 之前 它在两者中都运行良好 但在 2015 04 24 发布的 OpenCV 3 0 中不适用于视频文件 如果有人知道 O
  • 将字符串分解为Python中的字符列表[重复]

    这个问题在这里已经有答案了 本质上 我想从文件中提取一行文本 将字符分配给一个列表 并创建一个列表中所有单独字符的列表 列表的列表 目前 我已经尝试过 fO open filename rU fL fO readlines 这就是我所拥有的
  • 错误CS0116:命名空间不能直接包含字段或方法等成员

    好吧 我正在尝试制作一个程序来检查程序当前是否正在运行 每当我声明无效时 它都会给我一个错误 我是 C 新手 所以如果它很愚蠢 我很抱歉 using System using System Windows using System Coll
  • 在 WPF 中实现暂停

    这里有一个简单的 WPF 程序
  • Singleton:应该如何使用

    编辑 在另一个问题中 我提供了一个答案 其中包含许多有关单例的问题 答案的链接 关于单例的更多信息在这里 所以我已经阅读了该主题单身人士 好的设计还是拐杖 而且争论仍然很激烈 我将单例视为一种设计模式 好的和坏的 Singleton 的问题
  • 如何使用 Selenium 设置私人代理?

    几天来我一直在尝试使用 Firefox 在 Selenium 中设置私有代理 带身份验证 然而 无论我做什么 我都没有成功 目前 我已经尝试了以下两种方法 在这两种情况下 Firefox 都能正常启动没有任何代理 Proxy proxy n
  • 即使 OkHttp 不是依赖项,OkHttp 连接泄漏日志行也是如此

    当我使用我的应用程序时 我不断在 Logcat 中看到以下日志行 19098 19147
  • 关闭后如何清除dialog/xmlfragment内容? [复制]

    这个问题在这里已经有答案了 我的对话框定义为document onOpenDialog function var oView this getView var oDialog oView byId helloDialog create di
  • 如何通知 GCC 不要使用特定寄存器

    假设我有一个非常大的源代码并打算制作rdx在执行期间完全未使用寄存器 即在生成汇编代码时 我想要的只是通知我的编译器 GCC 它不应该使用rdx at all 注 注册rdx这只是一个例子 我对任何可用的 Intel x86 寄存器都满意
  • 我的类名与 Ruby 的类名冲突

    我的模块中有一个名为 Date 的类 但是当我想使用用 ruby 打包的 Date 类时 它会使用我的 Date 类 module Mymod class ClassA class Date lt Mymod ClassA require
  • 控制CPU利用率

    在运行时如何控制CPU利用率是明智的 轮询CPU负载并插入睡眠 我推荐操作系统功能 Windows 上有用于此目的的性能计数器和 WinAPI 函数 这是一个使用的示例性能计数器 from BCL 团队博客 foreach Process
  • 将 pyqtgraph 绘图嵌入到 QT .ui 中?

    首先 我希望您对我有一些耐心 因为我是此类项目的新手 我也希望不要问愚蠢的问题 话虽这么说 我的主要目标是为树莓派 3 创建一个 UI 它将感应电池和太阳能电池板的电压 电流等 由于我正在研究树莓派并且对Python3有一些了解 所以我决定
  • 从基于文本的表输出中提取列

    qfarm load命令显示我的服务器的负载 输出 PS gt qfarm load Server Name Server Load Load Throttling Load Logon Mode SERVER 01 400 0 Allow
  • Windows 10 上使用 IE 的量角器失败 - 错误代码 199

    我无法让量角器在 Windows 10 上使用 IE 11 它说Unable to create new service InternetExplorerDriverService并且存在代码 199 我尝试过旧的重新安装 升级节点 npm
  • 如何使用 Power Query 有效地密集表中的排名组

    我一直在尝试最简单的方法对具有组或类别的数据对以下数据进行密集排名 我已经问过类似的问题来对数据进行排名 但这是针对分组数据的 我希望对分数列进行排名 如下所示 使得最高的数字占据第一位置 第一 第二大的数字占据第二位 依此类推 如果有平局
  • 如何使用 Swift 1.2 确定 NS_ENUM 是否为未记录的值

    例如 定义了以下 NS Enum typedef NS ENUM NSInteger Type TypeNone 0 TypeA 1 var x 2 if let type Type Type rawValue x Swift 1 2 ex
  • 从服务器向客户端发送浮点数

    我在用TCP IP套接字编程 我有一个浮点值存储在变量中ret val在我的服务器代码中 我想将其发送给正在等待接收它的客户端 我该怎么做 如果您知道客户端和服务器是同一平台等 您可以简单地使用sizeof float 确定缓冲区大小并从浮
  • Project Tango:坐标系之间的转换和合并点云

    我正在尝试转换采样并存储在 XYZij 数据中的点云 根据document 将相机空间中的数据存储到世界坐标系中 以便可以合并它们 我用于 Tango 监听器的帧对有COORDINATE FRAME START OF SERVICE作为基础
  • 循环中 Plotly 中的 add_trace [重复]

    这个问题在这里已经有答案了 我想在循环中绘制多个轨迹 而不覆盖所有以前的轨迹 In 这个帖子从 2015 年开始 提出了在循环中添加跟踪的解决方案 通过设置evaluate TRUE在plot ly或add trace函数中 然而 从 20
  • 如何使用 forge 加密和解密 pdf blob 并将其存储在 localStorage 中?

    我试图加密一个 pdf 文件 Blob 并将其存储在 localStorage 中 并在离线时读取和解密它 我的应用程序是用 AngularJS 编写的 加密是用forge 这是我下载pdf文件的代码 http get url header