漏洞概要

缺陷编号:
暂无

漏洞标题:
安全防范:字符编码发展史和密码算法那些事儿

提交时间:
2017-07-14

危害等级:

相关厂商:

漏洞分类:
安全事件

关注度:
共 81 人关注

漏洞详情

安全防范:字符编码发展史和密码算法那些事儿


作者:vul.anbai.com



2017-07-14

安全防范:字符编码发展史和密码算法那些事儿,从《易经》开始:

宇宙万物,道法阴阳,阴阳未分为混沌,混沌即无极,演而有序,化为太极。

易有太极,是生两仪,两仪生四象,四象演八卦,八卦演万物。

阴阳术创造了一个世界,炊烟袅袅,鸟语花香。

二进制创造了另一个世界,有一个小男孩,已经醒来。

0×01 编码的故事

ASCII

一个神秘组织为了融入人类的语言符号,将二进制的单元八位一组,建立了一套符号对应关系表(例如 A => 01000001),即 ascii 表,它是符号表的始祖。PS:标准 ascii 表的第一位都是 0,因此只有128 个字符。

一句话总结:所有编码的爸爸。

gb2312/gbk/gb18030

聪明的天朝人民也想融入自己的文字。由于标准 ascii 字符首位为 0,他们用两个首位为 1 的字节(我=> 1100111011010010)组合来表示汉字。为了庆祝这种机智的做法,命名为 gb2312;加入繁体字后,发现还是不够用。让后面一个字节的首位也可以为 0 ,这样又可以多编码一倍的汉字,这种方案叫 gbk;再后来,加入少数民族文字,就有了 gb18030。

天朝另一个小区域一直在用繁体字,他们发明了 Big5 汉字编码。

一句话总结:中国特色的编码。

Unicode

“你们不可能每个人都这么乱搞一套编码吧?你们互不相懂,唧唧歪歪,互相伤害,还能好好做朋友吗?”另一个神秘组织终于忍不住了,“你们不是嫌 ascii 编码不了你们的文字么?那简单,我用 2个字节,把全世界所有的符号都统一编码起来。”这样就出现了 Unicode。最初用 2 个字节想表示所有字符的方案,叫做 UCS-2,这样最多能表示 65536个字符。突然有一天,这位小哥发现 2 个字节根本不可能编码世界上所有的字符,就有了后面的 UCS-4,用 4 个字节来统一编码总够了吧……

一句话总结:别闹了都听哥的。

utf-7/8/16/32

这样编码是好,然而传输呢?按照 UCS-2 方案,所有字符都需要两个字节来传输,例如要发送一个A,就要发送 0000000001000001 这么多位,很浪费有木有?而且在实际传输中,数字和字母这样的字符占绝大多数。机智的人们又想搞事情了,引用哈弗曼编码的思想,出现频率越高的字符用更短的编码传输,频率低的字符就用多一点的编码传输。

utf-8,即每次传输 8 位一组。

所以发送 A,传输时一组就够了,实际传输 01000001。

而发送“汉”,则需要三组才行, 实际传输 111001101011000110001001。其中蓝色 8 位是 Unicode编码的第一个字节,绿色 8 位是第二个字节。

utf-7,utf-16,utf-32 也是一样的道理。utf-7 期初是用于电子邮件,邮件以字母为主,ascii 实质也是7 位一组。后面 16 和 32 这两种分组没有流行起来。

PS:utf-8 传输简体汉字时,是按照 3 个字节传输的,这就有了 utf-8 是 3 个字节这样的说法。实际上在 UCS-2 下 utf-8 传输字符,用 1-3 都是有可能的哦^_^

另外经常写和字符有关程序的小伙伴,一定有这样一个经验,想要让 gbk 和 utf-8互转,都是先要转到 Unicode 哦。

一句话总结:按频率传输,节省流量。

0×02 更少的编码

前面这一小段故事讲完了,我们先休息一下,马上进入更有意思的话题。

话说天下大势,分久必合,合久必分。字符的编码由简入繁,势必也会化繁为简。那么如何用更少的字符去表示所有编码呢?

Quoted-printable 编码

ascii 有 127 个字符,而且很多符号甚至是不可打印的,那怎么才能让他们都能显示呢?这个简单,对于不可打印字符,就用“=XX”表示,其中 XX 是该字符的 ascii 编码。例如换页符(ascii 为 0C),就可以表示成 =0C。只需要 =和0-F 这17个字符哦^_^

一句话总结:即使不可打印,也要可见。

Base64/32/16 编解码

Base 家族原理类似,就是用少量字符表示更多字符,但是也不像二进制那么少。Base64 即用64 个字符来表示所有ascii,怎么做到的呢?

大写字母集 W = {A,B,C…Z} 共 26 个

小写字母集 w = {a,b,c…z} 共 26 个

数字集 d = {0,1,2…9} 共 10 个

符号集 s = {+,/}

这 64 个字符对应数字 0-63,转化成二进制则是 6 位。而 ascii 是用 8 位,6 和 8 的最小公倍数是 24 = 3 * 8 = 4 * 6,所以将3 个ascii 字符就能转化成4 个base64 字符。

ascii 的 ABC-> 010000010100001001000011 ->010000 010100001001000011 ->QUJD

同理 base32 是用 32 个字符即 5 位表示,5 * 8 = 8 * 5,所以 base32 会把 5 个 ascii 字符变成 8 字符哦。

PS:如果字符数不是3 的倍数,怎么办?看一下操作你就知道了。

A -> 01000001-> 01000001 0000-> QQ== 所以你会看到 base64 串后面有1或2个=。

另外有些不专业的销售,会说他们的产品是用 base64 加密的,客户就会立刻质疑他的产品!base64只是一种编码,它的实质还是明文,你说用它来加密,不是掩耳盗铃??

另外依照这种理论,那么我们的二进制是不是可以理解成 base2?ascii 就是 base128 嘛。

一句话总结:用我们常用的字符表示所有字符。

XX 编码,UU 编码

它们实质跟 base64 是一样的,也是用 64 个字符来表示,只是选取的字符和编排方式不同罢了,其实它们才是base64 的前身,慢慢演进,渐渐被base64 取代了。

一句话总结:长江后浪推前浪。

URL,HTML 编码

URL编码

采用“%+ascii”的方式对字符进行编码,比如:

http://www.wr.com?file=../../passwd -> http://www.wr.com?file=%2e%2e%2f%2e%2e%2fpasswd

HTML编码

采用“&#+十进制数字”或“&#x+十六进制数字”的方式对字符进行编码,比如:

ab ->

ac

一句话总结:新瓶装旧酒。

说了这么多,下面画个编码家族的家谱图:

 

 

0×03 古典密码

从这些编解码演化的过程中,相信各位看官也会感受到劳动人民的智慧。前面的只是热身,下面将进入今天的重头戏,密码学。

还是回到开头那句话,任何一种思想或者想法,都一定是为了解决实际问题而设计的。字符编码的故事,是为了解决字符的表示、显示和传输的问题。那么密码学是为了啥子呢?

相信 Bob,Alice 和 Ted 斗智斗勇的故事大家都看过,没有看过的可以百度一下,挺有意思的。数据传输的安全性包括以下三个性质:

机密性:数据被偷了,小偷不知道是啥。

完整性:数据被改了,接受方能够发现。

可用性:纯属废话,不能用还要你何用?

下面主要介绍密码学在前两条性质中的作用。

先来几个不算是密码的密码算法。为啥这样说呢,因为这些算法刚发明时,别人不知道是怎么计算的,因此无法根据“密文”还原出原来的信息,可以算作加密。后来被普及了,大家就都会算了,这时候你还说你加密了,你是不是当我傻?

凯撒密码

引用一句话 I came,I saw, I conquered. 多么霸气啊。这个以帝国霸主名字命名的密码学确实如此朴素。凯撒密码有两种模式:

(1)位移密码,就是讲明文每位都移动特定位数,例如 AbC 右移 4 位就变成 Efg.

那么我(I)想对你说:M pszi csy.

(2)查表密码,指定一张明文和密文对应的关系表,然后对着这个表进行加解密。例如:

 

 

Hello加密之后就变成 Axeeh,那么Ixkyxvm.

维吉尼亚密码

我理解它是一种升级版的凯撒密码,它引入一张 26*26 的密码表盘,可以设定一个密钥,然后按照查表的方式进行加解密。由于操作简单,不过多叙述。

ROT5/13/18/47

ROT13 就是右移 13 位的凯撒密码,后面的数字是移动位数,这种加密方法不限定在数字或字母上,也可以拓展到所有 ascii。

摩尔斯密码

.. … – .. .-.. .-.. .-.. — …- . -.—– ..-

当铺密码

这种密码感觉还是很有意思的,就是看汉字露出的笔画数,决定这个数字是几,例如“十”,上下左右四处漏出,所有他就是数字 4 。

告诉你一句表白:大中口由人甲工

猪圈密码,栅栏密码等,其原理差不多,就是通过一张事先约定好的密码表,然后将明文进行查表加解密。

PS :这些密码算法实现简单,只是对原始字符做了一种替换编码,想到即解决。因此这些算法深受考脑洞的 CTF 赛友的青睐,也只适合出现在比赛和游戏中。

0×04 现代密码算法

好了终于把这一段朴素的古典密码

作者:hack-cn.com

发表评论

电子邮件地址不会被公开。 必填项已用*标注