Python對(duì)于自定義字符表的Base64編碼求解
在CTF比賽中我們常常會(huì)遇到使用自定義字符表替換Base64編碼的情況,那么怎么處理這類問題呢?
說到自定義字符表(Alphabet Table)解碼Base64瓢对,我們先得知道Base64是如何進(jìn)行編碼操作的谬泌。接下來我們先來介紹一下Base64是怎么進(jìn)行編碼的蒋得。
首先我們先來引入ASCII碼表:
2由境、一個(gè)字節(jié)是8個(gè)比特,先找到對(duì)應(yīng)的ASCII碼拼卵,再將其轉(zhuǎn)化為8位的二進(jìn)制奢浑,轉(zhuǎn)化如下:
????H 對(duì)應(yīng)碼值為72,它對(duì)應(yīng)的二進(jìn)制是 01001000
????e對(duì)應(yīng)碼值為101腋腮,它對(duì)應(yīng)的二進(jìn)制是:01100101
????l對(duì)應(yīng)碼值為108雀彼,它對(duì)應(yīng)的二進(jìn)制是:01101100
????l對(duì)應(yīng)碼值為108,它對(duì)應(yīng)的二進(jìn)制是:01101100
????o對(duì)應(yīng)碼值為111低葫,它對(duì)應(yīng)的二進(jìn)制是:01101111
Base64的碼值是0-63详羡,所以用6位的二進(jìn)制就可以完全表示Base64的碼值(如:000000對(duì)應(yīng)十進(jìn)制0仍律,111111對(duì)應(yīng)的十進(jìn)制為63)嘿悬,將上面8位一組的二進(jìn)制變成6位一組的二進(jìn)制,由于上面是5*8=40個(gè)二進(jìn)制水泉,不能被6整除善涨,所以要加一組0將其變成48個(gè)二進(jìn)制數(shù)(如果還是不能整除窒盐,還要繼續(xù)補(bǔ)8個(gè)0,其實(shí)就是最小公倍數(shù)的倍數(shù))钢拧。
????原來:01001000 01100101 01101100 01101100 01101111 00000000
????現(xiàn)在:010010 000110 010101 101100 011011 000110 111100 000000
3蟹漓、然后將6位一組的二進(jìn)制計(jì)算出十進(jìn)制,再跟Base64的編碼表做對(duì)比源内,再將最后補(bǔ)位的0變成=,即可得到Base64字符
?
010010 對(duì)應(yīng)二進(jìn)制是:18葡粒,18對(duì)應(yīng)Base64字符為:S
000110 對(duì)應(yīng)二進(jìn)制是:6, 6對(duì)應(yīng)Base64字符為:G
010101 對(duì)應(yīng)二進(jìn)制是:21膜钓, 21對(duì)應(yīng)Base64字符為:V
101100 對(duì)應(yīng)二進(jìn)制是:44嗽交, 44對(duì)應(yīng)Base64字符為:s
011011 對(duì)應(yīng)二進(jìn)制是:27, 27對(duì)應(yīng)Base64字符為:b
000110 對(duì)應(yīng)二進(jìn)制是:6颂斜, ?6對(duì)應(yīng)Base64字符為:G
111100 對(duì)應(yīng)二進(jìn)制是:18夫壁, 18對(duì)應(yīng)Base64字符為:8
000000 補(bǔ)位的0變成=
所以Hello對(duì)應(yīng)的Base64編碼就是:SGVsbG8=
而我們?cè)谏鲜鲞^程中多少數(shù)字對(duì)應(yīng)的多少的Base64字符,這個(gè)就是使用了Base64標(biāo)準(zhǔn)的Alphab Table沃疮,標(biāo)準(zhǔn)得Table如下:
我們?cè)谑褂肞ython去解決自定義表的Base64編碼的時(shí)候盒让,我們?cè)撛趺慈プ瞿兀拷酉聛磉M(jìn)行到我們的正題:
其實(shí)很簡單司蔬,我們將自帶的Base64中他的原始Table使用str中的maketrans類進(jìn)行替換即可邑茄,為什么呢?
我們通過上述的編碼過程可以進(jìn)行分析俊啼,我們?cè)诰幋a的過程中只是在最后使用到了表撩扒,但是實(shí)際上表所對(duì)應(yīng)的我們?cè)嫉臄?shù)據(jù)信息是不變的,所以我們先對(duì)編碼過的內(nèi)容字符進(jìn)行替換即可得到正常的Base64編碼吨些,我們?cè)谶M(jìn)行解碼即可搓谆。
于是我們得到了如下的代碼:
import?base64
import?string
str1?=?"NhFpbUihxvB="
string1?=?"ZYXABCDEFGHIJKLMNOPQRSTUVWzyxabcdefghijklmnopqrstuvw0123456789+/"
string2?=?"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
print?(base64.b64decode(str1.translate(str.maketrans(string1,string2))))
上述代碼是一個(gè)將表替換為:
“ZYXABCDEFGHIJKLMNOPQRSTUVWzyxabcdefghijklmnopqrstuvw0123456789+/”的代碼。
我們?cè)賮砜纯慈绾芜M(jìn)行編碼
str2='BB,yyds!'.encode()
print(str(base64.b64encode(str2)).translate(str.maketrans(string2,string1)))
上述就是使用替換字符表的加密編碼豪墅。
這次的代碼很簡單泉手,但是要理解str字符串類中的translate方法是包含了maketrans這種子方法的。