解决方案:加盐加密算法BCrypt
关键词
- 对称加密(单钥),非对称加密(公私钥),数字签名
- BCrypt加密(加盐)
一、对称加密算法
(1)定义:
采用单钥密码系统的加密方法,同一个密钥可以同时用作信息的加密和解密,这种加密方法称为对称加密,也称为单密钥加密。
(2)要素:
原文、秘钥、算法
秘钥:在密码学中是一个定长的字符串、需要根据加密算法确定其长度
(3)工作过程:
通常使用的是相对较小的密钥,一般小于256 bit。因为密钥越大,加密越强,但加密与解密的过程越慢。如果你只用1 bit来做这个密钥,那黑客们可以先试着用0来解密,不行的话就再用1解;但如果你的密钥有1 MB大,黑客们可能永远也无法破解,但加密和解密的过程要花费很长的时间。密钥的大小既要照顾到安全性,也要照顾到效率。
加密:明文 + 密钥 -> 密文
解密:密文 + 密钥 -> 明文
(4)算法
DES(Data Encryption Standard):数据加密标准(使用比较少,加密强度不够,能够暴力破解)
3DES:原理和DES几乎是一样的,只是使用3个密钥,对相同的数据执行三次加密,增强加密强度。(缺点:要维护3个密钥,大大增加了维护成本)
AES(Advanced Encryption Standard):高级加密标准,用来替代原先的DES,目前美国国家安全局使用的,苹果的钥匙串访问采用的就AES加密。是现在公认的最安全的加密方式,是对称密钥加密中最流行的算法。
AES128和AES256主要区别是密钥长度不同(分别是128bits,256bits)、加密处理轮数不同(分别是10轮,14轮),后者强度高于前者。
(5)特点
优点:算法公开、计算量小、加密速度快、加密效率高。
缺点:相对来说不算特别安全,只有一把钥匙,密文如果被拦截,且密钥也被劫持,那么,信息很容易被破译。
二、非对称加密算法
(1)简介:
非对称加密是计算机通信安全的基石,保证了加密数据不会被破解。
非对称加密算法需要两个密钥:公开密钥(public key) 和私有密钥(private key)
公开密钥和私有密钥是一对
(2)特点:
如果用公开密钥对数据进行加密,只有用对应的私有密钥才能解密。
如果用私有密钥对数据进行加密,只有用对应的公开密钥才能解密。
由于其算法复杂,而使得加密、解密速度没有对称加密解密的速度快。有两种密钥,其中一个是公开的,这样就可以不需要像对称密码那样传输对方的密钥了,这样安全性就大了很多。
(3)常用算法:
RSA、DSA、ECDSA
(4)推演 - 非对称加密
公钥加密:f1 ( publicKey,data ) = X
私钥解密:f2 ( privateKey,X ) = data
私钥加密:f3 ( privateKey,data) = X
公钥解密:f1 ( publicKey,X) = data
私钥保存在服务端,公钥保存在客户端,私钥永远不对外暴露
三、数字签名
(1)数字签名有两种功能:
能确定消息确实是由发送方签名并发出来的,因为别人假冒不了发送方的签名。
数字签名能确定消息的完整性,证明数据是否未被篡改过。
(2)数字签名如何生成
将要发送的数据先用Hash算法(摘要算法、散列算法)生成消息摘要,然后用发送者的私钥加密生成数字签名,与原文一起传送给接收者。
接下来就是接收者校验数字签名的流程了。
(3)校验数字签名流程
接收者只有用发送者的公钥才能解密被加密的摘要信息,然后用HASH函数对收到的原文产生一个摘要信息,与上一步得到的摘要信息对比。如果相同,则说明收到的信息是完整的,在传输过程中没有被修改,否则说明信息被修改过,因此数字签名能够验证信息的完整性。
假设消息传递在客户端、服务器之间发生。
服务器将消息连同数字签名一起发送给客户端
客户端接收到消息后,通过校验数字签名,就可以验证接收到的消息就是服务器发送的。
四、BCrypt加密
通常对密码进行加密,然后存放在数据库中,在用户进行登录的时候,将其输入的密码进行加密然后与数据库中存放的密文进行比较,以验证用户密码是否正确。 目前,MD5和BCrypt比较流行。相对来说,BCrypt比MD5更安全。
BCrypt 官网:http://www.mindrot.org/projects/jBCrypt/
(1)我们从官网下载源码
(2)新建工程,将源码类BCrypt拷贝到工程
(3)新建测试类,main方法中编写代码,实现对密码的加密
String gensalt = BCrypt.gensalt();//这个是盐 29个字符,随机生成
System.out.println(gensalt);
String password = BCrypt.hashpw("123456", gensalt); //根据盐对密码进行加密
System.out.println(password);//加密后的字符串前29位就是盐
(4)新建测试类,main方法中编写代码,实现对密码的校验。BCrypt不支持反运算,只支持密码校验
boolean checkpw = BCrypt.checkpw("123456", "$2a$10$61ogZY7EXsMDWeVGQpDq3OBF1.phaUu7.xrwLyWFTOu8woE08zMIW");
System.out.println(checkpw);