1.Bcrypt算法简介

 $2a$10$nEsRnVKwA2Jvm9xwZ3CVs.Dgjn19y5Wim/DP6nzb4xxmHEuF3SXym

这个密码是由 Spring Security 框架中内置的加密算法BCrypt生成的,号称最安全的加密算法

BCrypt是由Niels Provos和David Mazières设计的密码哈希函数,他是基于Blowfish密码而来的,并于1999年在USENIX上提出。

除了加盐来抵御rainbow table 攻击之外,bcrypt的一个非常重要的特征就是自适应性,可以保证加密的速度在一个特定的范围内,即使计算机的运算能力非常高,可以通过增加迭代次数的方式,使得加密速度变慢,从而可以抵御暴力搜索攻击。

Bcrypt可以简单理解为它内部自己实现了随机加盐处理。使用Bcrypt,每次加密后的密文是不一样的。

2.不可逆的MD5为什么是不安全的?

因为hash算法是固定的,所以同一个字符串计算出来的hash串是固定的,所以,可以采用如下的方式进行破解。

暴力枚举法:简单粗暴地枚举出所有原文,并计算出它们的哈希值,看看哪个哈希值和给定的信息摘要一致。 字典法:黑客利用一个巨大的字典,存储尽可能多的原文和对应的哈希值。每次用给定的信息摘要查找字典,即可快速找到碰撞的结果。 彩虹表(rainbow)法:在字典法的基础上改进,以时间换空间。是现在破解哈希常用的办法。 对于单机来说,暴力枚举法的时间成本很高(以14位字母和数字的组合密码为例,共有1.24×1025种可能,即使电脑每秒钟能进行10亿次运算,也需要4亿年才能破解),字典法的空间成本很高(仍以14位字母和数字的组合密码为例,生成的密码32位哈希串的对照表将占用5.7×1014 TB的存储空间)。但是利用分布式计算和分布式存储,仍然可以有效破解MD5算法。因此这两种方法同样被黑客们广泛使用。

3.对一个密码,Bcrypt每次生成的hash都不一样,那么它是如何进行校验的?

从图中可以看到同一个字符串每次加密之后生成的密码是不一样的,但是为什么可以解析成功呢?

1.虽然对同一个密码,每次生成的hash不一样,但是hash中包含了salt(hash产生过程:先随机生成salt,salt跟password进行hash); 2.在下次校验时,从hash中取出salt,salt跟password进行hash;得到的结果跟保存在DB中的hash进行比对。

比如:

 $2a$10$N9qo8uLOickgx2ZMRZoMyeIjZAgcfl7p92ldGxad68LJZdL17lhWy\__/\/ \____________________/\_____________________________/Alg Cost      Salt                        Hash复制代码

上面例子中,2a 表示的hash算法的唯一标志。这里表示的是Bcrypt算法。

10 表示的是代价因子,这里是2的10次方,也就是1024轮。

N9qo8uLOickgx2ZMRZoMye 是16个字节(128bits)的salt经过base64编码得到的22长度的字符。

最后的IjZAgcfl7p92ldGxad68LJZdL17lhWy是24个字节(192bits)的hash,经过bash64的编码得到的31长度的字符。

4.具体代码实现

PasswordEncoder 这个接口有三个方法:

encode方法接受的参数是原始密码字符串,返回值是经过加密之后的hash值,hash值是不能被逆向解密的。这个方法通常在为系统添加用户,或者用户注册的时候使用。

matches方法是用来校验用户输入密码rawPassword,和加密后的hash值encodedPassword是否匹配。如果能够匹配返回true,表示用户输入的密码rawPassword是正确的,反之返回fasle。也就是说虽然这个hash值不能被逆向解密,但是可以判断是否和原始密码匹配。这个方法通常在用户登录的时候进行用户输入密码的正确性校验。 upgradeEncoding设计的用意是,判断当前的密码是否需要升级。也就是是否需要重新加密?需要的话返回true,不需要的话返回fasle。默认实现是返回false。

4.1先导入Spring Security框架的依赖 (spring-security-crypto)

 <dependency><groupId>org.springframework.security</groupId><artifactId>spring-security-crypto</artifactId><version>5.3.8.RELEASE</version></dependency>

4.2创建Bean注入进去

 import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;​import java.security.SecureRandom;​@Configurationpublic class PasswordConfig {/*** 随机秘钥的长度*/private int seedLength = 32;/*** : 10 # 加密强度4~31,决定了密码和盐加密时的运算次数,超过10以后加密耗时会显著增加*/private Integer strength = 10;@Beanpublic BCryptPasswordEncoder passwordEncoder() {// 加密强度,数字越大强度越大,越安全,越耗时SecureRandom random = new SecureRandom(SecureRandom.getSeed(seedLength));return new BCryptPasswordEncoder(strength, random);}}

4.3 BCryptPasswordEncoder 是PasswordEncoder接口实现类直接拿到对象使用就行

@AutowiredBCryptPasswordEncoder bCryptPasswordEncoder;​// 注册用户存入密码的时候需要加密密码String encode = bCryptPasswordEncoder.encode("前端传入的初始密码");//将User保存到数据库表,该表包含password列user.setPassword(passwordEncoder.encode("前端传入的初始密码");​//注册完后登录验证密码  //结果为ture就是验证成功                boolean matches = bCryptPasswordEncoder.matches("前端传入的初始密码","数据库查到的密码"); ​//验证密码是否需要升级//结果为flase就是不需要升级 默认是不需要升级                   boolean encoding = bCryptPasswordEncoder.upgradeEncoding("加密之后的密码--encode");

passwordConfig.java

 @Configurationpublic class PasswordConfig {/*** 随机秘钥的长度*/private int seedLength = 32;/*** : 10 # 加密强度4~31,决定了密码和盐加密时的运算次数,超过10以后加密耗时会显著增加*/private Integer strength = 10;@Beanpublic BCryptPasswordEncoder passwordEncoder() {// 加密强度,数字越大强度越大,越安全,越耗时SecureRandom random = new SecureRandom(SecureRandom.getSeed(seedLength));return new BCryptPasswordEncoder(strength, random);}}

Bcrypt算法(随机加盐,每次加密后的密文都是不一样的)相关推荐

  1. salt加盐MD5加密代码

    普通的md5因为其代表的密码是一致的,这里说的比较抽象,看下面举的例子 例如一串密码wer123456,加密后可能会是b6a6c36f9d25aa74(瞎写的) 其中w,e,r,1,2,3,4,5,6 ...

  2. RSA算法习题 (采用RSA算法,其中e=7,p=11,q=13,求出公钥和私钥,并求出明文85进行加密后的密文。)

    1.采用RSA算法,其中e=7,p=11,q=13,求出公钥和私钥,并求出明文85进行加密后的密文. 2. 找出质数 P.Q P=11 Q=13 3. 计算公共模数 N = P * Q = 143 4 ...

  3. Openssl ECC椭圆曲线算法 - 密钥/签名/验签/加密/解密/SM2密文 - 序列化反序列化导出导入 - C源码

    . . . . 废话不多说,本代码继承自另外一位讲解Openssl ECC椭圆曲线算法大佬的源代码:https://blog.csdn.net/scuyxi/article/details/59182 ...

  4. 趣图:每次变更后,我们都做了测试

    (给程序员的那些事加星标,每天看趣图) 每次变更后,我们都做了测试 ↓↓↓ (汉化:雪糕@程序员的那些事) 往期趣图(点击下方图片可跳转阅读) 关注「程序员的那些事」加星标,每天看趣图 (商务合作QQ ...

  5. 为什么RSA公钥每次加密得到的结果都不一样?

    <<OpenSSL和Python实现RSA Key公钥加密私钥解密>>中提到,发现使用RSA公钥对同一数据加密,每次的结果都不一样.百度一下,很多人都有这个疑问,但并没有看到详 ...

  6. BCrypt算法加密解密

    BCrypt的密码加密 介绍 BCrypt算法是目前使用比较广泛的加密解密算法,SpringSecurity中提供了BCryptPasswordEncoder类. 优点 自己写的加密算法或者MD5,同 ...

  7. 国产加密实际运用:使用SM3加盐存储密码,并且使用SM2进行登录认证

    目录 1.简要 2.开发环境及工具 3.后台密码加密部分 3.1加密代码 3.2 SM3加密类(Sm3crypto) 3.3国密SM3工具类(Sm3Utils) 3.4国密相关依赖包 4.登录认证部分 ...

  8. BCrypt算法的基础使用

    BCrypt算法是一种基于哈希算法的算法,所以,这种算法也是不可逆的! 应用场景:用于存放密码,卡号等不可解密的数据信息 在开发实现中,通常,可以使用配置类中的@Bean方法来创建BCryptPass ...

  9. Spring Security BCryptPasswordEncoder 密码加盐

    Spring Security BCryptPasswordEncoder 密码加盐 引入spring-boot-starter-security 的Jar包 <dependency>&l ...

  10. 给密码加盐是什么东西?

    1. 用户的密码如何保存在数据库中 假设小明的账号是 ikun 密码是 jinitaimei 那么我们可以设计一张表, 来保存账号密码 CREATE TABLE account ( username ...

最新文章

  1. linux系统文件介绍
  2. [你必须知道的css系列]第一回:丰富的利器2:CSS选择符之子选择符、相邻选择符...
  3. C++对象内存模型学习
  4. Linux 工程师技术 系统服务管理进阶
  5. linux 指定范围内查找文件,Linux Find命令查找指定时间范围内的文件的例子
  6. SpringBoot--自动装配之Import注解以及源码分析
  7. 【Java学习笔记】之家庭账目管理系统
  8. apizza的使用方法
  9. 抖音小店无货源,出现退货的情况怎么处理?千万别大意
  10. 知网查重报告html乱码,知网查重报告出现乱码怎么办
  11. IT系统架构及架构体系详解
  12. SAP ERP和ORACLE ERP的区别是哪些?
  13. 电动车登记上牌系统源码免费分享
  14. IE8兼容html5视频播放
  15. 认识DSR评分,如何补充DSR评分
  16. 【优化】seo之提升网站流量的四种方法
  17. [唐诗]古风(其十九)-李白
  18. windows操作系统知识最全
  19. spring boot自动化配置
  20. Python 画樱花树(樱花树下的约定)

热门文章

  1. 计算机考研838难吗,苏州大学808 管理学_福州大学838_ 福州大学431考研难不难考研到底难不难...
  2. canvas简易时钟
  3. 【C】Malloc与结构体,其实就是C语言里面的new和类
  4. 怎样用计算机对图形图像处理,计算机图形图像处理技巧图形设计论文(全文完整版)...
  5. 三角形单元刚度矩阵matlab,平面3节点三角形单元刚度矩阵matlab程序
  6. 你扔过来的沟通最简单
  7. 2021高考语文成绩作文查询,新鲜出炉!2021高考语文作文题全在这里
  8. mysql商品和图片表的意思,MySQL----商品表及商品分类表例子
  9. quartus导入sdc文件
  10. 报错:The value parameter,it‘s name ‘xxxx‘ already exsts. please set a unique name for the parameter .