base64 编码详解

base64 原理

base64 是密码学中, 最基础的编码

base 64

**他是一种编码 **

还有 其他的 base家族 16 32 91 85 是按照 对照表的大小 给定的64

3 个字节 变成 4 个字节

3 个字节 = 24 bit

24 / 6 = 4(字节)

然后每6 bit 的前面补上00

然后按照 base64 对照表

不够3 * 8 即结尾的位置 会在 后面补0 直到满足3 * 8 的条件

base64的解码

  1. 检查 base64 编码后面有几个等于号
  2. 把字符串按照 base64 表 转换成 4 * 6 的倍数位二进制
  3. 删除等于号的个数 * 8 的bit
  4. 按照6 个 bit 一组转成字符

python 的 base64 编码解密

import base64

base64.b64encode(要编码的数据)

base64.b64decode(要解码的数据)

返回来的 是 bytes 类型的数据

base64 隐写术

利用了 base64 解码时 , 会删除 等于号的个数 * 8 的 bit , 而且我们只用6 个 bit 标识一个等于号(000000),那么,意思就是 我们可以控制等于号 * 2bit 的字符

image-20200721171519777

如图, 那么我们就可以在加粗的 0 的位置 用 二进制隐写. 这样子做, 不影响原文的还原( 因为解码的时候加粗位置被改的数 是要被删除的), 唯一的区别就是, 上如的 QQ== 中,第二个 Q 会变化, QkM= 的M 会变化, 所以 base64可以用于隐写

base64 换表解

import base64
import string

str1 = "x2dtJEOmyjacxDemx2eczT5cVS9fVUGvWTuZWjuexjRqy24rV29q"      # 要解码的数据

string1 = "ZYXABCDEFGHIJKLMNOPQRSTUVWzyxabcdefghijklmnopqrstuvw0123456789+/"   # 改变位置后的 base64 表
string2 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"  # 原表

print (base64.b64decode(str1.translate(str.maketrans(string1,string2))))

base64 隐写术 爆破脚本

#coding=utf-8
def get_base64_diff_value(s1, s2):
    base64chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
    res = 0
    for i in xrange(len(s2)):
        if s1[i] != s2[i]:
            return abs(base64chars.index(s1[i]) - base64chars.index(s2[i]))
    return res


def solve_stego():
    with open('stego.txt', 'rb') as f:
        file_lines = f.readlines()
        bin_str = ''
        for line in file_lines:
            steg_line = line.replace('\n', '')
            norm_line = line.replace('\n', '').decode('base64').encode('base64').replace('\n', '')
            diff = get_base64_diff_value(steg_line, norm_line)
            print diff
            pads_num = steg_line.count('=')
            if diff:
                bin_str += bin(diff)[2:].zfill(pads_num * 2)
            else:
                bin_str += '0' * pads_num * 2
            print goflag(bin_str)


def goflag(bin_str):
    res_str = ''
    print bin_str
    for i in xrange(0, len(bin_str), 8):
        res_str += chr(int(bin_str[i:i + 8], 2))
    return res_str


if __name__ == '__main__':
    solve_stego()

这个脚本 是python2 的

总结

一个萝卜一个坑,知识是慢慢积累的。

原文地址:https://www.cnblogs.com/shenshuoyaoyouguang/p/14422436.html