简介

  Base64是一种非常常用的数据编码方式,标准Base64可以把所有的数据用"A~Z,a~z,0~9,+,/,="共65个字符(‘=’号仅是一个占位符,作为后缀)表示,当然在遇到的一些CTF题中也会有变种Base64作为加密算法来用,Base64运用范围是很广的,但是这里只讨论在安卓逆向中较为常见的URL编码和变种Base64

编码方式

  在标准base64中,每行最多有76个字符(仅在Intent相关内有这个定义,如MIME,但是如果是别的领域不一定要满足这个),在每行结束的时候添加回车换行符“\r\n”,在windows系统中,“\n”是类似于箭头“↓”的功能,将光标向下平移。而“\r”是键盘“Home”功能,即将光标移动到首位。所以需要使用回车换行符才能达到Linux里的"\n"效果,即将光标往下平移至首位。还有就是在URL中,由于'+','/','='都是特定的意义,所以一般会对应的用'-','_','.'等替换。

  标准Base64是一种编码方式而非加密方式最大的原因就是因为它的可逆,它的编码方式也很简单:

    1. 先将所有的字符由ASCⅡ转换为二进制串,例如:c o d转换为0110 0011(99)  0110 1111(111)  0110 0100(100)
    2. 将所有的二进制串连接,并按6个比特为一组,即011000
    3. 在每组比特前补上两个高位0,即:00011000  00110110  00111101 00100100
    4. 再根据下表转换,如本例中的00011000  00110110  00111101 00100100 即为24 54 61 36,即Y29k

   但是上述中我们也能发现不少问题,比如按我一开始说的有65个字符,那么“=”号去哪了呢?再如8*3=4*6,所以我们可以分为四组,每组六个比特,但如果我们的输入数据有4个或者5个等不可被3整除的长度呢?其实在解决办法中,这两者有联系。

  既然有多余的长度,那就再后补零,比如上例子中,若输入数据是coda,那在cod操作之后,还剩下a,即0110 0001,同样转换为:

    1. 011000 01,往后补零为:011000 010000
    2. 补位00011000(24) 00010000(16)
    3. 查表转换为YQ

  那“=”号呢?有人说等号是用来判断长度余下几位的,如余一位(4位,7位等)则用两个等号标识,若余两位,则用一个等号标识。

  但是仔细想想就发现这个说法明显是错的,毕竟不管怎么说,若正好是三位一组的话,转为base64后也就是对应的4位一组,而除4,余下来的只可能是3和2(0和1在Base64编码里是不可能出现的),通过多余的字符数量,自然就可以知道输入数据的长度了。所以等号的用处就是:Base64规定要以4位字符为一组,所以你得加上这个等号。也就是说,如果是自己定义的话,这个等号也是可以不用加的。

变种Base64

  既然已经知道了Base64的编码规则,那如果我们自己定义一些规则,就可以变成自己的变种base64,比如上述的“=”号,很多人都会用等号来判断是否是Base64的编码方式,但是经过分析之后就看得出,这个“=”号在编码中并不影响逆向编码,所以就可以删除最后的这个添加等号的判断;再比如标准Base64中的密码表是很规则的"A~Z....",但是这个密码表我们可以自己改,将其中间几个元素位置打乱是不是就可以修改为自己的base64了呢。

最后附上标准base64的加解密Python代码

加密:

#来源于百度百科
def base(string:str)->str:
oldstr = ''
newstr = []
base = ''
base64_list = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
'w', 'x', 'y', 'z', '', '', '', '', '', '', '', '', '', '', '+', '/']
#把原始字符串转换为二进制,用bin转换后是0b开头的,所以把b替换了,首位补0补齐8位
for i in string:
oldstr += '{:08}'.format(int(str(bin(ord(i))).replace('0b', '')))
#把转换好的二进制按照6位一组分好,最后一组不足6位的后面补0
for j in range(0, len(oldstr), 6):
newstr.append('{:<06}'.format(oldstr[j:j + 6]))
#在base_list中找到对应的字符,拼接
for l in range(len(newstr)):
base += base64_list[int(newstr[l], 2)]
#判断base字符结尾补几个‘=’
if len(string) % 3 == 1:
base += '=='
elif len(string) % 3 == 2:
base += '='
return base

解密:

 #我也忘了来源于哪了
base64_charset = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
#base64密码表
def decode(base64_str):
base64_bytes = ['{:0>6}'.format(str(bin(base64_charset.index(s))).replace('0b', '')) for s in base64_str if
s != '=']
resp = bytearray()
nums = len(base64_bytes) // 4
remain = len(base64_bytes) % 4
integral_part = base64_bytes[0:4 * nums] while integral_part:
tmp_unit = ''.join(integral_part[0:4])
tmp_unit = [int(tmp_unit[x: x + 8], 2) for x in [0, 8, 16]]
for i in tmp_unit:
resp.append(i)
integral_part = integral_part[4:] if remain:
remain_part = ''.join(base64_bytes[nums * 4:])
tmp_unit = [int(remain_part[i * 8:(i + 1) * 8], 2) for i in range(remain - 1)]
for i in tmp_unit:
resp.append(i)
return resp

密码学习(一)——Base64的更多相关文章

  1. [CTF]栅栏密码学习

    [CTF]栅栏密码学习 即把将要传递的信息中的字母交替排成上下两行,再将下面一行字母排在上面一行的后边,从而形成一段密码.栅栏密码是一种置换密码. 例如密文:TEOGSDYUTAENNHLNETAMS ...

  2. go标准库的学习-encoding/base64

    参考:https://studygolang.com/pkgdoc 导入方式: import "encoding/base64" base64实现了RFC 4648规定的base6 ...

  3. python学习之base64模块

    常见方法: base64.encodebytes() 参数: 接收一个字节对象. 返回值: 返回base64编码的数据(以'\n'结尾的数据). base64.decodebytes() 参数: 接收 ...

  4. 一步一步从原理跟我学邮件收取及发送 2.邮箱的登录和绕不开的base64

    一步一步从原理跟我学邮件收取及发送 2.邮箱的登录和绕不开的base64 好了,经过本系列上一篇文章 "1.网络命令的发送",假设大家已经掌握了 email 电子邮件的命令发送的方 ...

  5. 学习使人快乐7--Mail收发原理+计划

    本篇了解邮件收发的原理与机制(smtp,pop3协议).不打算作重点学习辣~~~~~~~~~~~~~~~~ 日常感谢大佬gacl 另:打算把每周计划学的东西发在blog上面,勉励一下本咸鱼本周计划:1 ...

  6. Go web编程学习笔记——未完待续

    1. 1).GOPATH设置 先设置自己的GOPATH,可以在本机中运行$PATH进行查看: userdeMacBook-Pro:~ user$ $GOPATH -bash: /Users/user/ ...

  7. SpringCloud学习心得—1.3—Eureka与REST API

      SpringCloud学习心得—1.3—Eureka与REST API Eureka的REST API接口 API的基本访问 Eureka REST APIEureka 作为注册中心,其本质是存储 ...

  8. python-网络安全编程第七天(base64模块)

    前言 睡不着,那就起来学习其实base64模块很早之前用过今天做爬虫的时候有个URL需要用它来编码一下 所以百度又学了一下遇到最大的问题就是python3和python2区别问题 python3的这个 ...

  9. 加密算法中BASE64、MD5、SHA、HMAC等之间的区别

    http://blog.csdn.net/lplj717/article/details/51828692 根据项目需要了解了一下几种加密算法(参考其他博客),内容简要介绍BASE64.MD5.SHA ...

随机推荐

  1. 【网络流】One-Way Roads

    [网络流]One-Way Roads 题目描述 In the country of Via, the cities are connected by roads that can be used in ...

  2. BinarySearchTree(二叉搜索树)原理及C++代码实现

    BST是一类用途极广的数据结构.它有如下性质:设x是二叉搜索树内的一个结点.如果y是x左子树中的一个结点,那么y.key<=x.key.如果y是x右子树中的一个结点,那么y.key>=x. ...

  3. 工作常见的git命令

     Git创建项目仓库: 1.git init 初始化   2.git remote add origin url 关联远程仓库   3.git pull  拉取远程仓库到本地  相当于(git fet ...

  4. [LC] 659. Split Array into Consecutive Subsequences

    Given an array nums sorted in ascending order, return true if and only if you can split it into 1 or ...

  5. 树分治(挑战p360)

    poj1741 题:http://poj.org/problem?id=1741 #include<iostream> #include<algorithm> #include ...

  6. 《ECMAScript 6 入门教程 - 阮一峰著》学习笔记

    在刷LeetCode的过程中看到很多新的语法糖,系统学习一下以便代码更加规范,美观,健壮.

  7. winfrom控件圆角

    刚好用到这个功能,看了好些例子.我就不明白,简单的一个事,一些文章里的代码写的那个长啊,还让人看么. 精简后,就其实一点,只要有paint事件的组件,都可画圆角,没有的外面套一个panel就行了. u ...

  8. Estimating Gene Frequencies| method of maximum likelihood|point estimate

    I.11 Estimating Gene Frequencies 在小样本上计算基因A的概率PA,举例如下: 通过加大样本会将通过观察值得到的数趋近于真实数据,所以该问题转化为了统计学上利用大量观察值 ...

  9. Leetcode13_罗马数字转整数

    题目 罗马数字包含以下七种字符: I, V, X, L,C,D 和 M. 字符 数值I 1V 5X 10L 50C 100D 500M 1000例如, 罗马数字 2 写做 II ,即为两个并列的 1. ...

  10. SecureCRT8.1安装破解

    博主本人平和谦逊,热爱学习,读者阅读过程中发现错误的地方,请帮忙指出,感激不尽 一.安装破解 [基本信息] SecureCRT v8.x 注册机,TEAM Z.W.T 出品,MD5 = 44114b9 ...