token要加编码decode吗_彻底弄明白Base64 编码

Base64 encoding/decoding常见于各种authentication和防盗链的实现当中。彻底搞懂它绝对提升团队troubleshooting的底气。我们从纯手工方式编码解码开始,然后看看学到的技能怎么样应用在实际的troubleshooting 中。

准备工作:我们应知道一个byte有8个bits,并且知道怎么表示它。

我们应该comfortable with hex, binary and decimal 之间的conversion.

有一张现成的ASCII table. (网上有很多,我下面附一个直接带binary value的)

Base64 Table

Base64 Encoding的原理

大白话是这样。给定一个bits序列,从最左开始,按顺序每6-bit 为一组进行分组,这样每一组可以表示最多2的6次方,也就是64个字符。这是为什么它叫Base64的原因。

这样分组,最后即最右边的一组如果正好有6-bit, 分组就完成。如果不够6-bit, 就要做一个alignment / padding的处理。有两步。第一步,用binary 0 (bit 的值为0)补齐到6-bit. 如果补过的bit 序列正好落在byte boundary,则分组完毕;如若不然,继续第二步,补到下一个最近的byte boundary, 不过不是用0去pad, 而是用等号字符“=”, 用1个或者2个等号去补, 别忘了,一个等号占6个bits.

用数学的方式正规一点的描述是这样。

给定一个长度为L的bit 序列,L可以被8整除 ( 这也是byte boundary含义), 我们需要找到两个正整数M和N, 使得: L <= M <= N, 其中 M要能够被6整除, N is either L or L + 8.

根据这个描述可以得出下面这些结论:最后得到的长度为N的bit 序列也是落在byte boundary上,即N可以被8 整除。

L除以6的余数只有三种可能: 0,2, 4, 对应于三种不同的padding scenarios.

M - L 的 值只可能为: 0, 2, 4, 道理同上

N – M的值只可能为: 0, 6,12, 同样的,这是对应于三种不同的padding scenarios.

纯手工Base64编码

Given an input string “a”,

Step 1: 将它convert 成 bit 序列

查ASCII table, 我们得到它的binary value 即 bit 序列: 01100001

这是一个长度为8的初始序列。

Step 2: 按6个bits 一组分组

011000 01

Step 3: 最右组只有2 个bit, 不够6 bits, 需要补4个0

011000 010000

至此我们可以得到两个字符:

011000 = 2 ** 4 + 2 ** 3 = 16 + 8 = 24, 查Base64 table, 对应于24的字符是 Y.

010000 = 2 ** 4 = 16, 同样查Base64 table, 对应于16的字符是 Q

很多Base64的实现,到这就结束了。小写 a, 经过Base64编码之后就是YQ.

Step 4: 这原始bit 序列长度为8, Step 3补了4个0, 变成12,不能被8整除,继续补。

我们知道从12开始,下一个被8整除的值是24, 所以我们要补24 – 12 = 12个bits. 在这种情况下我们补等号字符,一个字符占6 bits,所以我们补两个”= “.

如果做了这一步,小写 a, 经过Base64编码之后就是YQ== .

纯手工Base64 解码

Given YQ==,

Step 1: 去掉“=”的padding, 得到 YQ, 同时知道pad了12 bits 到byte boundary.

Step 2: 根据Base64 table convert “YQ” to bit 序列 011000 010000

Step 3: 去掉 最右边pad的4个0

因为原始字符也就是要decode过去的字符是跳 8的,现在有12 bits, 很快可以确定最右4 bits 是padding.

从这种工作方式我们可以看到,既然最右4 bits无论如何都是要去掉的,这4 bits 可以是任何2 ** 4 = 16个值中的一个,而不影响decoding的结果。举几个例子:

0110000 010001 = YR

0110000 010010 = YS

0110000 010011 = YT

0110000 011110 = Ye

0110000 011111 = Yf

下面是用Python Bas64 module decoding的结果,验证上面所讲。

>>> base64.b64decode("YR==")

'a'

>>> base64.b64decode("YT==")

'a'

>>> base64.b64decode("YU==")

'a'

>>> base64.b64decode("YV==")

'a'

>>> base64.b64decode("YW==")

'a'

>>> base64.b64decode("YY==")

'a'

>>> base64.b64decode("YZ==")

'a'

>>> base64.b64decode("Ya==")

'a'

>>> base64.b64decode("Yb==")

'a'

>>> base64.b64decode("Yf==")

'a'

>>> base64.b64decode("Ye==")

'a'

>>>

Step 4: 按8-bit 分组, 得到 011000 01, 这个就是”a”.

实例分析

Linkedin发现如果他们修改防盗链token的最后一位,authentication仍然可以通过,要我们解释。

Token in question是这样的:

bs3xODAExQFZthY2LF1EqbuVtq4veLftiHILz3pXn13Ai5DzRYmdCZ8O9FAQwI4zceyBpEJO6secbKz9rGNMfBVeNaplwLNVqQwAXSR-grVQGJkz91pqdmVBbrwCpGto5IazBV8XDMJUIGCGZOdld2REqemD4cvDoLdeN3itZirB2FGfMHPxhP0

如果把末尾0换成1,2, 3, authentication 仍旧可以通过。

前面学到的东西可以马上应用。思路是这样的:

Token 长度为183, 所以bit 序列的长度为183 * 6 = 1098. 因为1098 没有落在byte boundary, 我们可以立即确定encoding 的Step 4省略了,即没有pad “=”.

因为1098 / 8 = 137 r2, 我们可以确定 最右的2 bit 是padding. 如前所述, 这两个bits 可以是 任何 2 ** 2 = 4个值中的一个,而不影响decoding的结果。

00 = 0

01 = 1

10 = 2

11 = 3

至此Linkedin 的问题彻底解释清楚。

读了这一篇,你应该可以回答为什么有的Base64-encoded的values 末尾没有等号,有的有一个等号,有的有两个等号,以及为什么多个values会decode到相同的value. If necessary, you should be able to base64 encode and decode pretty much anything MANUALLY.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/393864.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

oracle的oradata,Oracle使用oradata恢复数据库

SQL> host del D:\oracle\ora92\database\PWDoracle.ORASQL> host orapwd fileD:\oracle\ora92\DATABASE\PWDoracle.ORA passwordsystem entries10SQL> alter database open;数据库已更改。SQL> conn system/system as sysdba已连接。SQL> shutdown immediate数…

Jenkins连接TFS出现错误:“jenkins com.microsoft.tfs.core.exceptions.TECoreException”的问题收集...

没成功解决过&#xff0c;下面提供一些收集的链接地址&#xff0c;因为这个问题真的很少。 https://social.msdn.microsoft.com/Forums/vstudio/en-US/1a75a0b2-4591-4edd-999a-9696149c8144/integration-with-jenkins?forumtfsintegration http://www.itgo.me/a/900879197026…

leetcode842. 将数组拆分成斐波那契序列(回溯)

给定一个数字字符串 S&#xff0c;比如 S “123456579”&#xff0c;我们可以将它分成斐波那契式的序列 [123, 456, 579]。 形式上&#xff0c;斐波那契式序列是一个非负整数列表 F&#xff0c;且满足&#xff1a; 0 < F[i] < 2^31 - 1&#xff0c;&#xff08;也就是…

react fiber_让我们爱上React Fiber

react fiberby Ryan Yurkanin瑞安尤卡宁(Ryan Yurkanin) 让我们爱上React Fiber (Let’s fall in love with React Fiber) TLDR, React Fiber is an internal engine change that allows React to break the limits of the call stack. It’s creation enables React to pause…

Ajax爬取豆瓣电影目录(Python)

下面的分析相当于一个框架&#xff0c;搞懂之后&#xff0c;对于类似的文字爬取&#xff0c;我们也可以实现。就算不能使用Ajax方法&#xff0c;我们也能够使用相同思想去爬取我们想要的数据。 豆瓣电影排行榜分析 网址&#xff1a;https://movie.douban.com/explore#!typemovi…

到底死不死我就请了七天假_“你到底死不死?我只请了7天假”

这两天看到一条令人心酸的新闻&#xff0c;在国内某地铁站内&#xff0c;一位57岁的大妈突发心脏病&#xff0c;被紧急救醒后&#xff0c;第一句话竟是请求工作人员不要打电话通知她远在德国的儿子。看完这条新闻&#xff0c;掌柜特别心酸&#xff0c;孤身一人在国内&#xff0…

正面管教PHP沙龙,正面管教沙龙体会

接触到正面管教这个理念是我们南宁行动派伙伴圈 的圈主西西给大家带来的分享&#xff0c;谢谢西西[爱你]图片发自简书App同时也很感谢亲切温柔&#xff0c;知性优雅的Liliane老师&#xff0c;让我明白表扬和鼓励的区别&#xff0c;非暴力教育……教书育人这个道路上我需要学习的…

FB面经Prepare: Dot Product

Conduct Dot Product of two large Vectors 1. two pointers 2. hashmap 3. 如果没有额外空间&#xff0c;如果一个很大&#xff0c;一个很小&#xff0c;适合scan小的&#xff0c;并且在大的里面做binary search 1 package fb;2 3 public class DotProduct {4 5 publi…

leetcode1291. 顺次数(回溯)

我们定义「顺次数」为&#xff1a;每一位上的数字都比前一位上的数字大 1 的整数。 请你返回由 [low, high] 范围内所有顺次数组成的 有序 列表&#xff08;从小到大排序&#xff09;。 示例 1&#xff1a; 输出&#xff1a;low 100, high 300 输出&#xff1a;[123,234] …

20175223 MySQL

目录 完成结果要求 1 &#xff1a;导入world.sql要求 2 &#xff1a;CityWanna.javaCityWanna.java要求 3 &#xff1a;CountryWanna.javaCountryWanna.java要求 4 &#xff1a;LifeWanna.javaLifeWanna.java过程中问题及解决1. XAMPP无法启用 MySQL 程序。目录 完成结果 要求 …

2020运动相机推荐_2020年超有价值入门级微单相机推荐,超高性价比几款入门级微单相机(选购指南)...

学习摄影专业已经3年多啦&#xff0c;自己喜欢拍摄照片&#xff0c;自己还帮助过一些想学习摄影的朋友快速入门&#xff0c;最近发现周围学习摄影的朋友也越来越多了&#xff0c;有一些朋友咨询关于入门微单相机的问题&#xff0c;想让推荐几款不错的入门的微单相机。这篇文章带…

javascript入门_JavaScript代理快速入门

javascript入门What is a JavaScript proxy? you might ask. It is one of the features that shipped with ES6. Sadly, it seems not to be widely used.什么是JavaScript代理&#xff1f; 你可能会问。 这是ES6附带的功能之一。 可悲的是&#xff0c;它似乎并未得到广泛使用…

linux缺少文件操作数,linux 文件的atime,ctime,mtime查看与修改

查看ls -a默认显示的是修改时间ls -c / --timestatus / --timectime显示的是状态修改时间(即权限修改时间)ls -u / --timeuse / --timeaccess / --timeatime表示的是文件访问时间修改touch: 缺少了文件操作数请尝试执行“touch --help”来获取更多信息。[weilocalhost ~]$ touc…

leetcode47. 全排列 II(回溯)

给定一个可包含重复数字的序列&#xff0c;返回所有不重复的全排列。 示例: 输入: [1,1,2] 输出: [ [1,1,2], [1,2,1], [2,1,1] ] 代码 class Solution {List<List<Integer>> cListnew ArrayList<>();public List<List<Integer>> permuteUni…

linux 磁盘查看方式

fdisk (查看物理磁盘大小) df (查看文件系统&#xff0c;也就是正在使用磁盘大小) lsblk (查看逻辑磁盘大小)转载于:https://www.cnblogs.com/MUQINGFENG123/p/10820345.html

ioslabel阴影,UILabel的内阴影

is it possible to create such a UILabel with inner and outer shadow?i only know shadowColor and shadowOffsetzoomed:thanks!解决方案The answer by dmaclach is only suitable for shapes that can easily be inverted. My solution is a custom view that works with …

Webpack初学者介绍

Webpack is a tool that lets you compile JavaScript modules. It’s also known as a module bundler.Webpack是使您可以编译JavaScript模块的工具。 也称为模块捆绑器 。 Given a large number of files, it generates a single file (or a few files) that run your app.给…

Android Coding利器之掌握小技巧,助你Coding更上一层楼~

本文讲的是Android Coding利器之掌握小技巧&#xff0c;助你Coding更上一层楼~&#xff0c;话说前几天在网上浏览到一大牛写的关于Android布局优化的文章&#xff0c;看后感触很深&#xff0c;回过头看看自己写过的代码&#xff0c;发现还是有不少需要改进&#xff0c;今天找不…

linux系统报警怎么办,常见Linux系统故障和解决方法

常见Linux系统故障和解决方法发布时间&#xff1a;2020-06-06 14:48:19来源&#xff1a;亿速云阅读&#xff1a;212作者&#xff1a;Leah栏目&#xff1a;云计算这篇文章给大家分享的是常见的Linux系统故障和解决方法。在使用系统的过程中总会有各种各样的故障&#xff0c;所以…

Vuex 模块化与项目实例 (2.0)

Vuex 强调使用单一状态树&#xff0c;即在一个项目里只有一个 store&#xff0c;这个 store 集中管理了项目中所有的数据以及对数据的操作行为。但是这样带来的问题是 store 可能会非常臃肿庞大不易维护&#xff0c;所以就需要对状态树进行模块化的拆分。 首先贴出一个逻辑比较…