在我们日常的程序开发中,或多或少会遇到一些加密/解密的场景,比如在一些接口调用的过程中,我们(Client)不仅仅需要传递给接口服务(Server)必要的业务参数,还得提供Signature(数字签名)以供Server端进行校验(是否是非法请求?是否有篡改?);Server端进行处理后返回给Client的响应结果中还会包含Signature,以供校验。本篇博客将从Java程序员的角度出发,通俗理解加密、解密的那些事!
假设场景:client需要发送一段消息"hello world"给server
单向加密
所谓单向加密是指client将消息"hello world"加密的过程不需要server参与,即加密不依赖server;同时,server将受到的消息解密成"hello world"的过程也不依赖client。 例如,咱们知道的MD5就是一种单向加密算法,是一种不可逆的算法。
对称加密
client加密消息需要依赖server,双方可以相互解密。
非对称加密
client加密消息需要依赖server,但是双方不能相互解密。
先看一段代码:
BASE64编码/解码测试
需要注意的是,BASE64Encoder和BASE64Decoder并不是官方JDK实现类,如果需要使用,需要引入sun.misc包。 严格来说,BASE64并不是一种加密算法,而是一种编码格式。说白了,BASE64的作用是,将人肉眼可以识别的信息,转换为不可以识别的数据,并不是对数据进行加密,只是给数据换了一身衣服而已。(骗的了你的眼睛,骗不了程序) 原数据越大,那么BASE64生成的结果就越大,这是需要额外注意的点。 BASE64的生成结果始终由64个字符来组成。 由于BASE64的编码特性,在一些场景中有应用,比如有些网站会把图片的二进制流编码成BASE64传递给客户端;比如有些邮件服务器会将邮件的附件直接编码成BASE64连同邮件内容一起发送;比如在URL中有中文需要传递,可以先将中文进行BASE64编码,来避免传输过程中的乱码。
MD5,即Message Digest,信息摘要算法第5版。比如在和微信支付、支付宝支付接口交互的过程中,你就可以选择MD5算法来加密。
先来看一段代码:
MD5
MD5破解? 如前文所说,MD5是一种不可逆的算法,但是为什么存在破解呢?其实,所谓的破解,并不是真正的破解,只不过是大数据查询的一个碰撞而已。比如,有一台服务器存储了大量key以及key的MD5编码的信息,那么就可以拿着数据去进行比对。 那么实际场景中,一般我们如何防止这种暴力破解呢? 答案:进行二次加密。 比如client在调用server接口的时候,server分配给client一个Token,每次client调用server接口的时候,需要对Token以及业务参数一起进行MD5加密。其实这就是所谓的一个“加盐”的过程。
MD5的一些特性分析
第一,我们知道BASE64随着原数据的增大而导致编码后的结果长度变大,而MD5结果的长度值是固定的,就是32位。也就是MD5的压缩性很好。 第二,从原数据计算出MD5是一个快速且容易的过程,不可逆。 第三,要找到2个不同的数据,它们计算后的MD5一致,这是非常困难的。这是MD5的弱碰撞性,也即是说想要伪造数据太困难了。 第四,对原数据的任何修改,哪怕只改动一个字节数据,也会导致MD5值发生很大变化,说明MD5的抗修改性非常好,非常适合密码、业务数据校验、文件比对等。
SHA,即Security Hash Algorithm,安全散列算法,比如,我们的程序开发完毕,我们发布的时候,想指定的人才可以使用,该怎么办呢?这个时候就可以考虑使用SHA算法。SHA是公认的比MD5更加安全的加密算法,在数字签名领域应用广泛。
好了,到这里,初步介绍了下和咱们JAVA程序员有关的一些加密的知识,重点介绍了BASE64和MD5,加密算法的水太深了,欢迎大家拍砖指教,^_^