前几天,有个开发问我“Jimmy,你好。请问我这个信息已经使用Base64加密了为何还不满足安全需求?”
听到这句话之后,我有点“吃惊”,Base64不是加密算法,只是一个编码方法,根本就不能保护信息的机密性。看来,我们还有可能有不少人分不清它们的用途。随之,便产生一想法,写一篇编码和加密的文章,分析一下编码和加密,让大家了解一下它们的区别。
下面就介绍一下加密和编码的一些概念和作用。
加密
加密是通过Intranet、Extranet和Internet进行安全的信息交换的基础。从业务的角度来看,通过加密实现的安全功能包括:身份验证,使收件人确信发件人就是他或她所声明的那个人;机密性,确保只有预期的收件人能够阅读邮件;以及完整性,确保邮件在传输过程中没有被更改。从技术的角度来看,加密是利用数学方法将邮件转换为不可读格式从而达到保护数据的目的的一门科学。
加密算法有三种:对称加密算法和非对称加密算法以及哈希算法。
对称加密算法
简单地说就是,加密和解密都是用同一个密钥的加密算法。其加密过程如下
对称加密算法可以起到的作用是:保密和认证。保密就是对消息进行了加密,其他人看不到消息的内容;认证是只有有密钥的人才可以发这个消息(密钥泄漏的情况除外)。
对称加密算法又可以分为流加密和块加密。流加密就是每次加密一个bit,块加密是将别加密的数据分成若干固定长度的块,每次加密一块。
常用的对称加密算法有以下几种模式:
模式 |
英文全称 |
中文 |
加密种类 |
ECB |
Electronic codebook |
电子密码本模式 |
块加密 |
CBC |
Cipher-block chaining |
加密块链模式 |
块加密 |
CFB |
Cipher feedback |
密文反馈模式 |
流加密 |
OFB |
Output feedback |
输出反馈模式 |
流加密 |
CTR |
Counter |
计数器模式 |
块加密 |
目前,常用的是CBC模式,不过,既安全,性能又好的是CTR模式。
下面是常用的对称加密算法的介绍:
算法名称 |
算法类型 |
密钥长度 |
速度 |
资源消耗 |
|
AES |
对称block密码 |
128、192、256位 |
高 |
低 |
|
3DES |
对称feistel密码 |
112位或168位 |
低 |
中 |
非对称加密算法
非对称加密算法是加密和解密使用不同的密钥,一个叫做公钥,一个称为私钥。其加密过程如下:
非对称加密可以起到的作用是:保密,认证,数据完整性。保密就是通过接收者的公钥加密,这样只有接收者有私钥,只有接收者可以解密;认证是通过签名来实现的(签名描述如下)
从此图可以看出,发送者使用自己的私钥签名,接收者只能使用发送者的公钥才能验证签名,就可以知道是谁发的这条消息;完整性和上面这个签名的图也有示例,就是对发送的内容计算出哈希值,然后使用发送者的私钥对哈希值签名,只有使用接收者的公钥才能解密出这个哈希值,再和发送的内容计算出来的哈希值比较,可以保证数据在传输过程中没有被篡改。
下面是常用的非对称加密算法的介绍:
算法名称 |
算法类型 |
密钥长度 |
速度 |
资源消耗 |
RSA |
大整数分解 |
1024, 2048 |
高 |
低 |
ECC |
有限域上的椭圆曲线离散对数 |
160, 210 |
低 |
高 |
ECC相对于RSA的优势就是在计算的时候消耗的资源比较少,安全性也不比RSA低,所以在资源相对比较少的移动设备上可以采用ECC。
这里需要注意的是:公钥(对方的)用来加密,私钥用来签名,私钥不能用来加密来保护信息的机密性。
哈希
哈希算法严格来说,不能是一种加密算法,因为它不能起到加密的作用。它只是按照一定的算法,将任意长度的字节串通过计算得到一个固定长度的字节串。接收方需要使用同样的算法同样的输入计算出哈希值,在和传输的哈希值比较。单纯的没有Key的哈希值和CRC校验值起到的作用类似,只能预防无意的对消息的更改(例如传输过程中信号收到干扰),不能预防故意的攻击,因为篡改消息的人可以在篡改消息之后,再重新计算哈希值将原来的哈希值替换掉,接收者在这样的情况下无法判断消息是否被更改过。所以需要和签名或者Key结合,才能用于对消息的完整性验证。HMAC就是和Key结合来验证消息的完整性。
算法名称 |
输出大小 (bits) |
碰撞情形 |
MD5 | 128 | 是 |
SHA-0 | 160 | 是 |
SHA-1 | 160 | 有缺陷 |
SHA-256/224 |
256/224 |
否 |
SHA-512/384 | 512/384 | 否 |
对于表中碰撞情形不是“否”的哈希算法,建议不要使用。
对称加密算法的难点在于密钥的分发,非对称加密的算法的缺点是性能比较低。结合二者的优点,使用非对称加密算法协商密钥(密钥一般都不长),使用对称加密算法加密发送的内容,可以有效地解决两种加密算法的缺点,SSL/TLS正式这种思想的一个实现。
一般公司都会有一个关于加密算法的使用的标准,最好根据公司的规定使用允许的安全的算法。
编码
编码是信息从一种形式或格式转换为另一种形式的过程。解码,是编码的逆过程。从概念上可以看出,编码只是表现形式的转换,没有保密的作用,因为编码和解码的算法是公开的,只要知道是什么编码的内容,任何人都可以轻松地解码。
下面介绍几种常用的编码:
1. Base64, 16进制,Base32
这种类型的编码主要是将原来的信息用另外一种编码机制替换,可以将一些特殊字符转换为一些基本的没有危险的字符。这样无论是在何种形式的载体中传输或者显示,都不会对原来的环境造成破坏。
2. 多语种的编码 UTF-8, UTF-16,UTF-32, Unicode, ISO8859-1, GBK, GB2312
这里说的编码主要是对各种语言的编码。世界上有很多语言,汉语、日语、英语、拉丁语等等,它们在计算机里需要有一种表现形式,于是,就有了每种语言的编码(例如:GB2312是针对中文的编码)以及可以容纳所有语言的编码(例如:UTF-8)。
3. BER/DER编码
当你使用证书的时候,也可能听说过编码的概念,基本编码规则BER(Base Encoding Rule)和DER(Distinguished Encoding Rule),他们都是证书内容的编码方式,主要是为了以无歧义的易于理解的方式描述ASN.1(Abstract syntax Notation),BER/DER是把ASN.1的抽象值编码为字节串。编码的基本规则是“类型-长度-值”三段式结构,简称TLV(Type Length Value)。DER是BER的一个子集,它为每一个ASN.1类型制定唯一的编码方案,BER可以为每一个类型制定多个编码方案。具体的细节信息可以参考:http://en.wikipedia.org/wiki/Basic_Encoding_Rules#BER_encoding。
4. HTML编码,JS编码,URL编码
这类编码是针对脚本语言或者标签语言中的字符串中的特殊字符进行处理,以防这些特殊字符破坏了原来的语义。通过这类编码可以预防注入问题的发生。所以,当你接受输入或者输出信息到标签语言或者脚本语言中时,必须考虑编码,将特殊字符无害化处理。
最后,用一句话总结一下他们的区别:加密就类似于整容,现在的样子和原来的样子已经千差万别,要想认出他/她,只能通过身体的其他的特有的特征(密钥);编码类似于化妆,你依然可以看到她/他原来的样子(方法就是卸妆)。
本篇文章概要地描述了加密和编码的基本含义和区别,并简单描述了它们的作用,希望能够给大家对于加密和编码的理解能够有所帮助。