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.
token要加编码decode吗_彻底弄明白Base64 编码相关推荐
- python字符编码在哪里_快速入手Python字符编码
前言 对于很多接触python的人而言,字符的处理和语言整体的温顺可靠相比显得格外桀骜不驯难以驾驭. 文章针对Python 2.7,主要因为3对的编码已经有了很大的改善并且实际原理一样,更改一下操作命 ...
- java解码base64的png图片_使用PHP对图片进行base64编码和解码(png、jpg,声音、视频)...
为什么要对图片base64编码 base64是网络上最常见的传输8Bit字节代码的编码方式之一.base64主要不是加密,它主要的用途是把一些二进制数转成普通字符用于网络传输.由于一些二进制字符在传输 ...
- 一文轻松明白 Base64 编码原理
把图片丢进浏览器,打开sources能看到一长串字符串,这是图片的Base64编码.这一长串编码到底是怎么生成的呢? 我们接下来探索一下base64编码的原理 Base64 名称的由来 Base64编 ...
- golang中base64编码_MySQL中如何将字符串转为base64编码?
点击蓝字关注我们!每天获取最新的编程小知识! 源 / php中文网 源 / www.php.cn 在MySQL中,TO_BASE64()函数将字符串转换为以base-64编码的字符串并返回结 ...
- java 二进制 base64编码_java 按字节读写二进制文件(Base64编码解码)
最近在做项目时遇到这样一个需求:依次读取本地文件夹里所有文件的内容,转为JSON,发送到ActiveMQ的消息队列, 然后从MQ的消息队列上获取文件的信息,依次写到本地.常见的文件类型,比如.txt ...
- MySQL怎么存base64编码_MySQL中如何将字符串转为base64编码?
在MySQL中,TO_BASE64()函数将字符串转换为以base-64编码的字符串并返回结果.(相关推荐:<MySQL教程>) 语法TO_BASE64(str) 其中str是需要编码的字 ...
- python 文件编码的识别_【python】python编码方式,chardet编码识别库
环境: python3.6 需求: 针对于打开一个文件,可以读取到文本的编码方式,根据默认的文件编码方式来获取文件,就不会出现乱码. 针对这种需求,python中有这个方式可以很好的解决: 解决策略: ...
- idea 编码扫描插件_代码神器:拒绝重复编码,这款IDEA插件了解一下
作者:HeloWxlhttp://www.jianshu.com/p/e4192d7c6844 Easycode是idea的一个插件,可以直接对数据的表生成entity.controller.serv ...
- 编码规范重要性_沟通比您的编码技能更重要
编码规范重要性 TL; DR (TL;DR) Communication is More Important Than Your Coding Skills 沟通比您的编码技能更重要 A few sh ...
最新文章
- golang 获取 磁盘 内存 占用
- php 详解spl_autoload_register()函数
- 《C#设计模式》PPT及源码分享
- 使用OC进行iOS截屏,同时保证清晰度
- Qt之模式、非模式、半模式对话框
- Reddit热议:为什么PyTorch比TensorFlow更快?
- 物流机器人小车的运动控制与定位
- python连接php_PHP+Python,轻量维护超轻松
- 再提手机上网应该包月计费
- 微信小程序自定义弹窗,禁止page页面滚动。
- 市场部商业计划PPT模板
- Mysql 省市区字典(带层级,带经纬度,带拼音)字典版
- 手机扫描电脑百度网盘二维码,二维码无法刷新的解决办法
- 解决Macm苹果笔记本电脑白屏
- linux驱动编写之十六(块驱动设备初识)
- Xms Xmx PermSize MaxPermSize的含义
- 编译原理——程序编译的基本流程
- 象棋棋谱xqf工具包 v2.02 绿色
- 20181213股票复盘
- 沙拉翻译网页双语显示,程序员必备,是神器没错了
热门文章
- RUNOOB python练习题29
- 公司想申请网易企业电子邮箱,怎么样?
- 马约拉纳费米子:推动量子计算的“天使粒子”
- 添加dubbo xsd的支持
- iframe中的历史记录问题汇总及解决方案[转]
- advanced installer更换程序id_好程序员web前端培训分享kbone高级-事件系统
- 从早期的初创企业到MongoDB的经理(播客)
- 将json 填入表格_如何将Google表格用作JSON端点
- 心学 禅宗_禅宗宣言,用于有效的代码审查
- 阿里的技术愿景_技术技能的另一面:领域知识和长期愿景