记一次手忙脚乱的base64debug之旅

2024-02-10 17:38

本文主要是介绍记一次手忙脚乱的base64debug之旅,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

这几天做了一个需求,读取上传的公私钥,然后利用私钥采用RSA加密摘要,发送给后端。其中运用到了base64的加解密,RSA加密采用的是node的Crypto模块,base64的转码采用的是js-base64, 然而万万没有想到,这里面有坑啊。

(开个玩笑,这个库还是很不错的)

文件的读取

首先是文件的读取,采用的是FileReader, 并且二进制文件的读取应为readAsArrayBuffer,否则会乱码。

readFile(file) {return new Promise((resolve, reject) => {const reader = new FileReader();reader.onload = function(evt) {resolve(evt.target.result)};reader.readAsArrayBuffer(file);})
}

从这里读取到的数据,调用Object.prototype.toString.call([data]),结果为[object Uint8Array]

ArrayBuffer对象用来表示通用的、固定长度的原始二进制数据缓冲区。ArrayBuffer不能直接操作,而是要通过类型数组对象或DataView 对象来操作,它们会将缓冲区中的数据表示为特定的格式,并通过这些格式来读写缓冲区的内容。

Uint8Array 数组类型表示一个8位无符号整型数组,创建时内容被初始化为0。创建完后,可以以对象的方式或使用数组下标索引的方式引用数组中的元素。

类型数组对象就是Uint8Array之类的TypedArray,我们需要这些对象操作ArrayBuffer

这是一个摸索了很久的点,因为有的公私钥读取可以直接采用reader.readAsText(file)

ArrayBuffer与base64的转换

另一个摸索了很久的东西便是ArrayBufferbase64的转换,缘由于js-base64对这两个的转换并不支持。

ArrayBuffer转base64

很令人捉🐔的是,调用库中的方法Base64.encode([ArrayBuffer]),得出的数据一直不对。
略微看了一下源码。

var _Base64 = global.Base64;
var version = "2.5.1";
// if node.js and NOT React Native, we use Buffer
var buffer;
if (typeof module !== 'undefined' && module.exports) {try {buffer = eval("require('buffer').Buffer");} catch (err) {buffer = undefined;}
}
...
var _encode = buffer ?buffer.from && Uint8Array && buffer.from !== Uint8Array.from? function (u) {return (u.constructor === buffer.constructor ? u : buffer.from(u)).toString('base64')}:  function (u) {return (u.constructor === buffer.constructor ? u : new buffer(u)).toString('base64')}: function (u) { return btoa(utob(u)) }
;
var encode = function(u, urisafe) {return !urisafe? _encode(String(u)): _encode(String(u)).replace(/[+\/]/g, function(m0) {return m0 == '+' ? '-' : '_';}).replace(/=/g, '');
};

不知是不是采用IIFE的关系,buffer恒为undefined,并且此时!urisafe为真,会流入第一个条件,而的uUint8Array,强制类型转换会导致乱码。

故而不用库,用原生方法。
Buffer.from([key]).toString('base64') 这是ArrayBufferbase64的原生方法。

base64转ArrayBuffer
function _base64ToArrayBuffer(base64) {var binary_string =  window.atob(base64);var len = binary_string.length;var bytes = new Uint8Array( len );for (var i = 0; i < len; i++)        {bytes[i] = binary_string.charCodeAt(i);}return bytes.buffer;
}

and…

const encryptDigest = crypto.privateEncrypt({ key: privateKey },Buffer.from(_base64ToArrayBuffer(digest))
);
const res = crypto.publicDecrypt({ key: publicKey }, encryptDigest);res.toString('base64') === digest ?

只要用私钥加密的摘要用公钥能成功解密,并且数据不变,就证明这个流程正确了。

其实用window.atob也可以将ArrayBufferbase64,但是有大小限制,码位应在 0x00 ~ 0xFF 范围内。然而后端小哥说业务不支持ascii格式的,只能作罢。

javascript – 将base64字符串转换为ArrayBuffer

深入学习 Node.js Buffer

这篇关于记一次手忙脚乱的base64debug之旅的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/697701

相关文章

(function() {})();只执行一次

测试例子: var xx = (function() {     (function() { alert(9) })(); alert(10)     return "yyyy";  })(); 调用: alert(xx); 在调用的时候,你会发现只弹出"yyyy"信息,并不见弹出"10"的信息!这也就是说,这个匿名函数只在立即调用的时候执行一次,这时它已经赋予了给xx变量,也就是只是

flume系列之:记录一次flume agent进程被异常oom kill -9的原因定位

flume系列之:记录一次flume agent进程被异常oom kill -9的原因定位 一、背景二、定位问题三、解决方法 一、背景 flume系列之:定位flume没有关闭某个时间点生成的tmp文件的原因,并制定解决方案在博主上面这篇文章的基础上,在机器内存、cpu资源、flume agent资源都足够的情况下,flume agent又出现了tmp文件无法关闭的情况 二、

jmeter之仅一次控制器

仅一次控制器作用: 不管线程组设置多少次循环,它下面的组件都只会执行一次 Tips:很多情况下需要登录才能访问其他接口,比如:商品列表、添加商品到购物车、购物车列表等,在多场景下,登录只需要1次,我们期望的是重复执行登陆后面的接口来做压测,这就和事务相关,例如 事务1: 登录—>添加购物车 事务2: 登录—>购物车列表 事务3: 登录—>商品列表—>添加购物车 … 一、仅一次控制器案例 在

一次生产环境大量CLOSE_WAIT导致服务无法访问的定位过程

1.症状 生产环境的一个服务突然无法访问,服务的交互过程如下所示: 所有的请求都是通过网关进入,之后分发到后端服务。 现在的情况是用户服务无法访问商旅服务,网关有大量java.net.SocketTimeoutException: Read timed out报错日志,商旅服务也不断有日志打印,大多是回调和定时任务日志,所以故障点在网关和商旅服务,大概率是商旅服务无法访问导致网关超时。 后

关于一次速度优化的往事

来自:hfghfghfg, 时间:2003-11-13 16:32, ID:2292221你最初的代码 Button1 34540毫秒 5638毫秒  Button2 我的代码 这个不是重点,重点是这个  来自:hfghfghfg, 时间:2003-11-13 16:54, ID:22923085528毫秒 不会吧,我是赛杨1.1G  128M内存  w2000, delphi6  128M

Spring Boot 注解探秘:HTTP 请求的魅力之旅

在SpringBoot应用开发中,处理Http请求是一项基础且重要的任务。Spring Boot通过提供一系列丰富的注解极大地简化了这一过程,使得定义请求处理器和路由变得更加直观与便捷。这些注解不仅帮助开发者清晰地定义不同类型的HTTP请求如何被处理,同时也提升了代码的可读性和维护性。 一、@RequestMapping @RequestMapping用于将特定的HTTP请求映射到特定的方法上

一次关于生产环境服务无故宕机的排查过程

故事的开始 这个故事是在一年之前,当时我们的系统运行在客户的k8s环境上。然后很神奇的是每个月底我们都会服务宕机,当然我们开启了多个实例。当时的容器线条就像心跳图一样(或许有些描述的不太准确,我没有找到当时那个像心电图一样的容器资源监控图)。 第一次的排查 当时我们还是很有信心去解决这个问题的。由于每个月的月底都是业务使用的高峰时段,也就是说,从表象上来看,qps一高,容器就挂。 业务日

28.8K Star,音乐新体验,开启你的高颜值音乐之旅

Hi,骚年,我是大 G,公众号「GitHub 指北」会推荐 GitHub 上有趣有用的项目,一分钟 get 一个优秀的开源项目,挖掘开源的价值,欢迎关注。 导语 音乐是生活中不可或缺的调味品,一个好的音乐播放器能够极大地提升我们的听觉享受。今天,我要向大家推荐一个名为 YesPlayMusic 的第三方网易云音乐播放器,它不仅拥有高颜值的界面设计,还支持跨平台使用,让你的音乐体验更上一层楼

杨bob的技术之旅

杨bob今天正式入驻csdn,以后要把自己每一点滴写成文章,这也是冲高阶的毕竟之路

记一次knife4j文档请求异常 SyntaxError: Unexpected token ‘<‘, ... is not valid JSON

knife4j页面报错问题定位 前几天开发新接口,开发完成后想使用knife4j测试一下接口功能,突然发现访问页面报错提示:knife4j文档请求异常,但之前运行还是正常的,想想会不会与升级依赖有关系,启动其他微服务发现文档接口访问正常,排除因依赖版本升级导致在线API文档无法使用情况,还是和本服务新增接口有关系。 定位问题 首先f12打开调试台,重新刷新页面,看到console有报错提示