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的解码
- 检查 base64 编码后面有几个等于号
- 把字符串按照 base64 表 转换成 4 * 6 的倍数位二进制
- 删除等于号的个数 * 8 的bit
- 按照6 个 bit 一组转成字符
python 的 base64 编码解密
import base64
base64.b64encode(要编码的数据)
base64.b64decode(要解码的数据)
返回来的 是 bytes 类型的数据
base64 隐写术
利用了 base64 解码时 , 会删除 等于号的个数 * 8 的 bit , 而且我们只用6 个 bit 标识一个等于号(000000),那么,意思就是 我们可以控制等于号 * 2bit 的字符
如图, 那么我们就可以在加粗的 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 的
总结
一个萝卜一个坑,知识是慢慢积累的。