網絡傳輸——Base64詳解
自從引用以來,Base64編碼的標準極普及為的迅速。不過,把文件作為附件通過網際郵件擴充協(xié)議(MIME)傳送時,Base64是標準的編碼標準。然而,幾乎所有的電子郵件客戶端都是用MIME發(fā)送文件(以附件形式)的,這就意味著大多數(shù)的電子郵件客戶端使用Base64對文件編碼后通過網絡傳輸。格式如下:
Content-Transfer-Encoding:base64( Gb2312)
這種傳輸格式又被稱為U-t-U(Unix to Unix)傳輸協(xié)議,能兼容大多數(shù)的硬件設備并基于其上進行無損字節(jié)傳輸。但是缺點在于是,使用此種格式會使文件的大小增加百分之四十左右。
除了作為MIME的默認編碼標準,base64編碼也廣泛用于其他領域。一個常見的例子是用于網絡服務器完成基于HTTP的基本認證。當服務器想限制訪問某些文件時,通過使用基于HTTP的基本認證系統(tǒng),便可以對這些文件進行密碼保護。而基本認證使用Base64編碼標準對用戶名和密碼進行編碼。這樣,黑客們使用TCP通過端口連接ESMTP服務器時,手動輸入量就會大大增加。
盡管Base64編碼受到廣泛的支持和應用,但卻是當今最弱的編碼標準之一,通過以下步驟就可以輕易地進行逆向工程。不僅僅是算法上的容易逆向,因為在網絡上Base64用純文本形式發(fā)送密碼,使得Base64加密文本很容易受到sniffer程序的嗅探。
編碼程序如下:
1、 將要加密的文本的每個字符轉換成標準的ASCII十進制碼。
2、 通過任何一種方式(手算、機器算、對照表格)將這部分十進制編碼轉換成二進制(文章最后附有轉換表)編碼。每個十進制碼都對應器等價的八位二進制數(shù)值。
3、 將這部分二進制數(shù)連結到一起,產生一串二進制數(shù)。
4、 將這一大片的二進制字符串分割成每6個字符為一部分的小塊。
5、 通過任何一種方式(手算、機器算、對照表格)將這部分6字符的小塊分別轉換成相應的等價十進制數(shù)。
6、 通過Base64表轉換成Base64編碼。
Base64編碼轉換表如下:
十進制 | 編碼 | 十進制 | 編碼 | 十進制 | 編碼 | 十進制 | 編碼 | ||
0 | A | 16 | Q | 32 | g | 48 | w | ||
1 | B | 17 | R | 33 | h | 49 | x | ||
2 | C | 18 | S | 34 | i | 50 | y | ||
3 | D | 19 | T | 35 | j | 51 | z | ||
4 | E | 20 | U | 36 | k | 52 | 0 | ||
5 | F | 21 | V | 37 | l | 53 | 1 | ||
6 | G | 22 | W | 38 | m | 54 | 2 | ||
7 | H | 23 | X | 39 | n | 55 | 3 | ||
8 | I | 24 | Y | 40 | o | 56 | 4 | ||
9 | J | 25 | Z | 41 | p | 57 | 5 | ||
10 | K | 26 | a | 42 | q | 58 | 6 | ||
11 | L | 27 | b | 43 | r | 59 | 7 | ||
12 | M | 28 | c | 44 | s | 60 | 8 | ||
13 | N | 29 | d | 45 | t | 61 | 9 | ||
14 | O | 30 | e | 46 | u | 62 | + | ||
15 | P | 31 | f | 47 | v | 63 | / | ||
例如:mne,通過ASCII字符表轉化為是進制值為:m、109,n,110,e、101.合起來就是:109110101.轉化為二進制就是:0110 1101 0110 1110 0110 0101。將它們分成六個字為一段:011011 010110 111001 100101。而他們對應的十進制字符分別是:27 22 57 37。Base64等價值就是:27、b,22、w,57、5,37、1,也就是說mne的Base64編碼是bw51。
需要注意的是:如果被加密的字符串每3個一組,還剩1或2個字符,使用特殊字符“=”補齊Base64成為4個字。
知道了加密方式,要逆向就很簡單了。將對應的Base64值轉換為十進制,再通過計算轉換成二進制編碼。將這一串碼分為8位1組,得到十進制碼,最后再等價到相應的ASCII編碼即可。
附1:ASCII編碼表(部分)
二進制 | 十進制 | 十六進制 | 縮寫/字符 | 解釋 |
0000 0000 | 0 | 00 | NUL (null) | 空字符 |
0000 0001 | 1 | 01 | SOH (start of handing) | 標題開始 |
0000 0010 | 2 | 02 | STX (start of text) | 正文開始 |
0000 0011 | 3 | 03 | ETX (end of text) | 正文結束 |
0000 0100 | 4 | 04 | EOT (end of transmission) | 傳輸結束 |
0000 0101 | 5 | 05 | ENQ (enquiry) | 請求 |
0000 0110 | 6 | 06 | ACK (acknowledge) | 收到通知 |
0000 0111 | 7 | 07 | BEL (bell) | 響鈴 |
0000 1000 | 8 | 08 | BS (backspace) | 退格 |
0000 1001 | 9 | 09 | HT (horizontal tab) | 水平制表符 |
0000 1010 | 10 | 0A | LF (NL line feed, new line) | 換行鍵 |
0000 1011 | 11 | 0B | VT (vertical tab) | 垂直制表符 |
0000 1100 | 12 | 0C | FF (NP form feed, new page) | 換頁鍵 |
0000 1101 | 13 | 0D | CR (carriage return) | 回車鍵 |
0000 1110 | 14 | 0E | SO (shift out) | 不用切換 |
0000 1111 | 15 | 0F | SI (shift in) | 啟用切換 |
0001 0000 | 16 | 10 | DLE (data link escape) | 數(shù)據鏈路轉義 |
0001 0001 | 17 | 11 | DC1 (device control 1) | 設備控制1 |
0001 0010 | 18 | 12 | DC2 (device control 2) | 設備控制2 |
0001 0011 | 19 | 13 | DC3 (device control 3) | 設備控制3 |
0001 0100 | 20 | 14 | DC4 (device control 4) | 設備控制4 |
0001 0101 | 21 | 15 | NAK (negative acknowledge) | 拒絕接收 |
0001 0110 | 22 | 16 | SYN (synchronous idle) | 同步空閑 |
0001 0111 | 23 | 17 | ETB (end of trans. block) | 傳輸塊結束 |
0001 1000 | 24 | 18 | CAN (cancel) | 取消 |
0001 1001 | 25 | 19 | EM (end of medium) | 介質中斷 |
0001 1010 | 26 | 1A | SUB (substitute) | 替補 |
0001 1011 | 27 | 1B | ESC (escape) | 溢出 |
0001 1100 | 28 | 1C | FS (file separator) | 文件分割符 |
0001 1101 | 29 | 1D | GS (group separator) | 分組符 |
0001 1110 | 30 | 1E | RS (record separator) | 記錄分離符 |
0001 1111 | 31 | 1F | US (unit separator) | 單元分隔符 |
附2:下列Perl腳本將會自動幫你做解密:
Use MIME::Base64;
Print decode_base64(“Insert Text here”);
附3:使用Java腳本實現(xiàn)解密(代碼):
<script type="text/javascript">
var base64EncodeChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
var base64DecodeChars = new Array(
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1,
-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
-1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1);
function base64Encode(str) {
var out, i, len;
var c1, c2, c3;
len = str.length;
i = 0;
out = "";
while(i < len) {
c1 = str.charCodeAt(i++) & 0xff;
if(i == len)
{
out += base64EncodeChars.charAt(c1 >> 2);
out += base64EncodeChars.charAt((c1 & 0x3) << 4);
out += "==";
break;
}
c2 = str.charCodeAt(i++);
if(i == len)
{
out += base64EncodeChars.charAt(c1 >> 2);
out += base64EncodeChars.charAt(((c1 & 0x3)<< 4) | ((c2 & 0xF0) >> 4));
out += base64EncodeChars.charAt((c2 & 0xF) << 2);
out += "=";
break;
}
c3 = str.charCodeAt(i++);
out += base64EncodeChars.charAt(c1 >> 2);
out += base64EncodeChars.charAt(((c1 & 0x3)<< 4) | ((c2 & 0xF0) >> 4));
out += base64EncodeChars.charAt(((c2 & 0xF) << 2) | ((c3 & 0xC0) >>6));
out += base64EncodeChars.charAt(c3 & 0x3F);
}
return out;
}
function base64Decode(str) {
var c1, c2, c3, c4;
var i, len, out;
len = str.length;
i = 0;
out = "";
while(i < len) {
/* c1 */
do {
c1 = base64DecodeChars[str.charCodeAt(i++) & 0xff];
} while(i < len && c1 == -1);
if(c1 == -1)
break;
/* c2 */
do {
c2 = base64DecodeChars[str.charCodeAt(i++) & 0xff];
} while(i < len && c2 == -1);
if(c2 == -1)
break;
out += String.fromCharCode((c1 << 2) | ((c2 & 0x30) >> 4));
/* c3 */
do {
c3 = str.charCodeAt(i++) & 0xff;
if(c3 == 61)
return out;
c3 = base64DecodeChars[c3];
} while(i < len && c3 == -1);
if(c3 == -1)
break;
out += String.fromCharCode(((c2 & 0XF) << 4) | ((c3 & 0x3C) >> 2));
/* c4 */
do {
c4 = str.charCodeAt(i++) & 0xff;
if(c4 == 61)
return out;
c4 = base64DecodeChars[c4];
} while(i < len && c4 == -1);
if(c4 == -1)
break;
out += String.fromCharCode(((c3 & 0x03) << 6) | c4);
}
return out;
}
alert("原文:"+sTemp+"\n加密:"+base64Encode(sTemp)+"\n解密:"+base64Decode(base64Encode(sTemp)));
alert("原文:"+sTemp+"\n加密:"+base64Encode(sTemp)+"\n解密:"+base64Decode(base64Encode(sTemp)));
</script>
好東西一般都放在最后的位置……
很高興你能看到這個文檔,說明你離過關又近了一步。
Tip:ZGIvc2lsaWMubWRi