不是重点,可以省略: 本人 七月的胜利。代表七月份我出生啦,嘻嘻
博客就是平常记录一些常用到的开发常用到的技术,方法等,看见好东西了就自己整理一下防止以后自己遇到了再找不到。
如果有幸帮到你,欢迎点个赞,写个评论。Thank you
需求
对于用户密码的保护,通常都会进行加密。我们通常对密码进行加密,然后存放在数据库中,在用户进行登录的时候,将其输入的密码与数据库中存放的密文进行比较,以验证用户密码是否正确。
BCrypt和MD5介绍
BCrypt加密: 一种加盐的单向Hash,不可逆的加密算法,同一种明文(plaintext),每次加密后的密文都不一样,而且不可反向破解生成明文,破解难度很大。
MD5加密: 是不加盐的单向Hash,不可逆的加密算法,同一个密码经过hash的时候生成的是同一个hash值,在大多数的情况下,有些经过md5加密的方法将会被破解。
Bcrypt生成的密文是60位的。而MD5的是32位的。
目前,MD5和BCrypt比较流行。相对来说,BCrypt比MD5更安全,但加密更慢。
虽然BCrpyt也是输入的字符串+盐,但是与MD5+盐的主要区别是:每次加的盐不同,导致每次生成的结果也不相同。无法比对!
BCrypt加密实现
第一种: 单独用BCrypt进行密码加密
1,添加依赖
1 2 3 4 5 | <dependency> <groupId>org.mindrot</groupId> <artifactId>jbcrypt</artifactId> <version>0.4</version> </dependency> |
2,代码
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 26 27 28 29 30 31 32 33 34 35 36 37 | public static void main(String[] args) { String password = "666666"; /** * 第一步:生成盐值salt * 调用BCrypt类的构造函数 * 有三个构造函数: * BCrypt.gensalt() * log_rounds为散列数因子,范围4-31,默认为10 * BCrypt.gensalt(int log_rounds) * random是随机数产生器,要使用的new SecureRandom()实例 * BCrypt.gensalt(int log_rounds, SecureRandom random) * */ String salt = BCrypt.gensalt(); /** * 第二步:生成加密字符串 * 调用BCrypt类的hashpw(String password, String salt)函数进行加密 * 其中password是明文密码,salt是第一步生成的盐值 */ String hashpw = BCrypt.hashpw(password, salt); System.out.println("明文:"+password); System.out.println("密文1:"+hashpw); /** * 第三步:验证密文是否正确 * 调用BCrypt类的checkpw(String plaintext, String hashed)函数 * plaintext 需要传入的明文 * hashed 为第二步加密后的密文 */ String plaintext = "666666"; boolean checkpw = BCrypt.checkpw(plaintext, hashpw); if (checkpw){ System.out.println("密码正确"); }else { System.out.println("密码错误"); } } |
第二种: 如果用到spring security安全框架,就直接用spring security 的依赖就可以
1,添加依赖
1 2 3 4 5 | <!-- spring security 安全认证 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> |
2,创建BCryptPasswordEncoder 类后调用其encode方法,BCryptPasswordEncoder类底层也是调用第一种方法。
1 2 3 4 5 6 7 8 9 10 11 12 | public static void BCryptTest(){ String password = "666666"; BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); // encode() 密码加密 String encode = passwordEncoder.encode(password); //matches 密码验证 if (passwordEncoder.matches("666666",encode1)){ System.out.println("密码正确"); }else { System.out.println("密码错误"); } } |
1 2 3 4 5 | for (int i = 1; i <10 ; i++){ BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); String encode = passwordEncoder.encode(password); System.out.println(encode); } |
MD5加密实现
1,添加依赖
1 2 3 4 | <dependency> <groupId>commons-codec</groupId> <artifactId>commons-codec</artifactId> </dependency> |
2, 代码
1 2 3 4 5 6 7 8 9 10 11 | public static void md5Test(){ String password = "x987654321d"; //盐/秘钥 随机数 String salt = UUID.randomUUID().toString().toUpperCase(); //带盐加密 String md5pw = DigestUtils.md5Hex(password + salt); //不带盐加密 String md5pw1 = DigestUtils.md5Hex(password); System.out.println("带盐 "+md5pw); System.out.println("不带盐 "+md5pw1); } |
MD5验证
第一步:把盐值和加密后的密文都存入数据库
第二步:验证时用输入的密码和数据库中存入的盐值进行再次进行加密后得到的密文和已经存入数据库中的密文进行比较。(这也是md5加密的缺点,如果密码相同,加密后的密文就相同。)
都是简单实现,如有不足请多指教!!!
奥利给