网络传输——Base64详解
自从引用以来,Base64编码的标准极普及为的迅速。不过,把文件作为附件通过网际邮件扩充协议(MIME)传送时,Base64是标准的编码标准。然而,几乎所有的电子邮件客户端都是用MIME发送文件(以附件形式)的,这就意味着大多数的电子邮件客户端使用Base64对文件编码后通过网络传输。格式如下:
Content-Transfer-Encoding:base64( Gb2312)
这种传输格式又被称为U-t-U(Unix to Unix)传输协议,能兼容大多数的硬件设备并基于其上进行无损字节传输。但是缺点在于是,使用此种格式会使文件的大小增加百分之四十左右。
除了作为MIME的默认编码标准,base64编码也广泛用于其他领域。一个常见的例子是用于网络服务器完成基于HTTP的基本认证。当服务器想限制访问某些文件时,通过使用基于HTTP的基本认证系统,便可以对这些文件进行密码保护。而基本认证使用Base64编码标准对用户名和密码进行编码。这样,黑客们使用TCP通过端口连接ESMTP服务器时,手动输入量就会大大增加。
尽管Base64编码受到广泛的支持和应用,但却是当今最弱的编码标准之一,通过以下步骤就可以轻易地进行逆向工程。不仅仅是算法上的容易逆向,因为在网络上Base64用纯文本形式发送密码,使得Base64加密文本很容易受到sniffer程序的嗅探。
编码程序如下:
1、 将要加密的文本的每个字符转换成标准的ASCII十进制码。
2、 通过任何一种方式(手算、机器算、对照表格)将这部分十进制编码转换成二进制(文章最后附有转换表)编码。每个十进制码都对应器等价的八位二进制数值。
3、 将这部分二进制数连结到一起,产生一串二进制数。
4、 将这一大片的二进制字符串分割成每6个字符为一部分的小块。
5、 通过任何一种方式(手算、机器算、对照表格)将这部分6字符的小块分别转换成相应的等价十进制数。
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) | 数据链路转义 |
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脚本实现解密(代码):
<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