zoukankan      html  css  js  c++  java
  • 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 的

    总结

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

  • 相关阅读:
    定义函数
    变量与常量
    字符串与格式化
    字符串与编码
    字符编码
    元组-tuple
    列表-list
    分支和循环
    润乾配置连接kingbase(金仓)数据库
    润乾报表在proxool应用下的数据源配置
  • 原文地址:https://www.cnblogs.com/shenshuoyaoyouguang/p/14422436.html
Copyright © 2011-2022 走看看