BCrypt加密算法的使用及原理

news2024/9/18 10:54:56

系列文章目录

1.SpringBoot整合RabbitMQ并实现消息发送与接收
2. 解析JSON格式参数 & 修改对象的key
3. VUE整合Echarts实现简单的数据可视化
4. List<HashMap<String,String>>实现自定义字符串排序(key排序、Value排序)
5. 使用JAVA代码实现生成二维码

更多文章可看我主页哦~


文章目录

  • 系列文章目录
  • 前言
  • 一、加密原理及代码
    • 1.1 原理
    • 1.2 代码
    • 1.3 运行效果
  • 二、原理
    • 2.1 密文随机生成
    • 2.2 passwordEncoder.matches 方法比较结果为什么都为true?
    • 2.3 如何提取加密后值中的盐
    • 2.4 提取盐之后,如何进行的比较
  • 三、如何运用
  • 四、为什么要用BCrypt算法进行加密
  • 总结


前言

    在我们开发过程中肯定会对于一些保密数据进行加密存储,加密的方式有很多,例如大家常见的MD5、SHA-256等加密方法。这边我以前使用的是MD5,主要是因为MD5容易被解密。因为MD5在值相同时,加密出的内容都是相同的。这样对于数据很容易就会被破解,怎样能做到相同值在加密后的值不相同呢?
    引入我们今天的主角BCrypt算法,BCrypt算法是一种用于密码散列的加密算法,设计用于安全地处理用户密码。它结合了散列算法和盐的使用,具有较高的安全性抗破解能力
    下面带大家了解BCrypt算法具体的使用方法以及一些原理的解析,让大家能够清晰的明白该算法的用途以及解决大家心中的疑惑~


一、加密原理及代码

1.1 原理

    相信大家在看这篇文章时也是见过BCrypt算法加密后的字符串样子,但对于里面的内容以及为什么会生成这样的字符串还不太明白,先来看下图:
在这里插入图片描述
上图中就是BCrypt算法生成字符串的结构组成,由四个部分组成:

  • 算法标识符 (2a):这个前缀表示使用了Bcrypt算法。 2 a 2a 2a是Bcrypt的一个版本标识符。
  • 代价因子 (10):代价因子表示算法的复杂度,也就是加密过程中迭代的次数。10表示算法使用2的10次方,即1024轮处理。这决定了计算哈希所需的时间和资源量。
  • 盐(Salt) :盐是一个16字节(128位)的随机值,用于增加哈希的唯一性和安全性。它经过Base64编码后变成22个字符的字符串。
  • 哈希值 (Hash):这是经过Bcrypt算法处理后的哈希值。它是24字节(192位)的原始哈希值,经过Base64编码后变成31个字符的字符串。

1.2 代码

    下面我们来使用代码生成字符串,因为相同值生成的密文是不同的,所以这里代码也做比较。是具体代码如下:

import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

public class test {
    // 创建 BCryptPasswordEncoder 实例
    private static final BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();

    /**
     * 加密密码
     *
     * @param rawPassword 明文密码
     * @return 加密后的密码
     */
    public static String encryptPassword(String rawPassword) {
        return passwordEncoder.encode(rawPassword);
    }

    public static void main(String[] args) {
        String password = "123456";
        String encryptedPassword = encryptPassword(password);
        String encryptedPassword1 = encryptPassword(password);
        // 比对加密后的密码
        boolean isMatch = passwordEncoder.matches(password, encryptedPassword);
        boolean isMatch1 = passwordEncoder.matches(password, encryptedPassword1);

        System.out.println("Encrypted Password: " + encryptedPassword);
        System.out.println("Encrypted Password1: " + encryptedPassword1);
        System.out.println("Passwords match: " + isMatch);
        System.out.println("Passwords match1: " + isMatch1);
    }
}

注:导入包security权限包,需要引入依赖。

1.3 运行效果

    从效果图可以看到,同样是进行原密码:123456的加密,加密的结果是不一样的。但是在通过原密码和加密后的密码对于时,都可以返回true。表名都是123456密码加密的。如下图所示:
在这里插入图片描述
这里大家可能会有2个疑问

  1. 为什么相同参数在加密时会生成不同的密文?
  2. 密文都不同了,怎么去和原密码进行的比较能得出结果呢?(即2个不同的密文,都和原文比较得出相同的结果)

二、原理

2.1 密文随机生成

  • 盐的使用:BCrypt 在加密过程中会生成一个独特的盐,并将其与密码进行混合。每次加密时,盐都会不同,因此即使原始密码相同,每次加密生成的加密值也会不同。

  • 加密过程:BCrypt 的加密过程包括盐的生成和散列计算。由于盐是随机的,生成的散列值会有所不同。即使输入相同,但由于每次使用不同的盐,输出也会不同。

    上述加密字符串的结构是由四部分组成的,其中包含盐。这里BCrypt自动生成一个随机盐值,盐的目的是防止相同密码生成相同的散列值。也正因为如此,hash值也会发现不一样。所以我们看到的加密字符串的内容是不一样的。

2.2 passwordEncoder.matches 方法比较结果为什么都为true?

注:passwordEncoder.matches 方法在比较密码时并不是直接比较加密后的值,而是执行以下步骤:

  • 提取盐:从加密后的值中提取盐。
  • 重新加密:使用提取出的盐和提供的密码重新计算加密值。
  • 比较:将重新计算的加密值与存储的加密值进行比较。

因为提取的是加密字符串中的盐,所以在传入的原密码使用提取的盐进行加密,得到的密文肯定是和一致的相同的盐散列值(hash)一样。所以会返回true,

大家在这里应该会比较清楚的知道输出效果图中的含义了。但是我来问大家一个问题:它是怎么提取加密后值中的盐呢?

2.3 如何提取加密后值中的盐

    这个其实第一张图认识字符串的组成结构时介绍了生成的规则。那么生成的规则也将是用来提取盐的重要部分:

  1. 首先底层会将加密的值进行拆分成四部分。
  2. 获取到盐的22个字符的字符串
  3. 因为这个字符串是BASE64加密后的,我们解码后也可以拿到一个16字节(128位)的随机值。

2.4 提取盐之后,如何进行的比较

  1. 使用提取出的盐原密码生成新的哈希值。此时原密码是必须的,因为新的哈希值是基于原密码和盐计算出来的。
  2. 将生成的哈希值与存储的哈希值进行比较。这一步确保了输入密码的正确性。

注:这里是重点,matches 方法比较原密码和加密是否一直时,是通过哈希值(也就是散列值)进行的比较。因为算法标识符 (2a)、代价因子(10)是固定的,盐的话也是通过密文去生成的,所以肯定一致。可能出现不一样的地方只有哈希值(因为哈希值的生成是通过提取出的盐和原密码生成的)

三、如何运用

    大家到这里应该对BCrypt算法有了一定的理解,但光了解原理是不够的。先说一下场景:我们以常见的密码存储为例:
数据库中的密码存储是相关重要的,都会使用加密算法实现。所以这里我们也可以运用BCrypt算法。

  1. 首先用户表密码字段需存入BCrypt算法加密的密文(这里在用户注册时,可通过下述代码生成密文)。
public static String encryptPassword(String rawPassword) {
        return passwordEncoder.encode(rawPassword);
    }
  1. 在用户登录时,通过用户名查询表,获取对应的实体。然后拿到实体中的密码作为matches(password, encryptedPassword);方法中的encryptedPassword参数,password就是用户输入的参数值。
  2. 调用matches方法查看返回值,如果返回true,则用户名和密码正确。否则返回“用户名或密码错误”。

这里简写一个实现代码,来体现步骤二、三。具体如下所示:

@PostMapping("/login")
    public R<User> login( @RequestBody User user){
      
        //1.将页面提交的密码
        String password=user.getPassword();

        //2.根据页面提交的用户名username查询数据库
        LambdaQueryWrapper<User> queryWrapper=new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getUsername,user.getUsername());
        User selectuser = userService.getOne(queryWrapper);
        // 比对加密后的密码
        boolean isMatch = passwordEncoder.matches(password, selectuser.getPassword());
        if(!isMatch){
            return R.error("用户名或密码不正确");
        }
        
        //封装token
        Map<String,Object> map=new HashMap<>();
//        map.put("token",token);

        return R.success(newUser,map);
    }

当然,这只是一个常规的场景需要用到对数据的加密。正常情况下对于表中的关键数据大多数都应该进行加密处理,例如用户的身份证号等重要信息值。这样即使是数据库数据泄露,也不会造成太大的影响,加密的数据很安全。

四、为什么要用BCrypt算法进行加密

    Bcrypt算法是一个密码哈希算法,它的好处有很多,专门设计用于保护密码存储,其主要优点包括:

  • 抗暴力破解:Bcrypt使用自适应的计算复杂度(代价因子),使得随着计算能力的提升,算法仍然能够保持其破解难度。这种自适应性增加了暴力破解的难度。
  • 内置盐:Bcrypt自动生成盐,并将其与哈希值一起存储。盐的使用防止了相同密码的哈希值重复,增强了安全性。
  • 抗彩虹表攻击:由于每个密码都包含独特的盐,即使两个用户使用相同的密码,哈希值也会不同。这使得预计算的彩虹表攻击变得不切实际。
  • 自适应性:代价因子(工作因子)可以调整,允许增加计算复杂度以抵御不断提高的计算能力。这使得Bcrypt能够应对未来的硬件进步。
  • 稳定性和可靠性:Bcrypt算法经过广泛使用和测试,被认为是一个成熟、可靠的密码哈希算法。
  • 防止硬件加速攻击:Bcrypt的设计旨在避免硬件加速攻击(例如GPU、FPGA等),因为它需要大量的计算资源,而不是简单的并行处理。

总结

    相信大家通读完全文后也对于BCrypt算法有了一定的理解。希望大家在日后的学习或者工作中能够运用到,对于数据的安全性是有很大帮助的。
    我在自己学习时也是遇到了很多的问题,本想着加密算法,没打算写文章的。但是在网上搜索时发现了很多文章介绍的不够全面,有些细节点在读完之后还是很疑惑。导致我在学习的过程中耗费了不少的时间成本。为了让大家的学习成本降低,所以写了这篇文章。希望大家能够通过这篇文章去理解和会去使用BCrypt加密算法~
    如果有什么问题都可以留言或者私信我哦~ 也希望大家有更多见解的朋友能够下方留言,让更多的人对BCrypt算法的知识点体会更加深刻~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1995006.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

69、zabbix自动、代理、snmp监控

一、zabbix 1.1、自动发现 [roottest1 ~]# systemctl stop firewalld [roottest1 ~]# setenforce 0 [roottest3 ~]# vim /etc/hosts 192.168.168.21 test1 192.168.168.23 test3 [roottest1 ~]# vim /etc/hosts 192.168.168.21 test1 192.168.168.23 test3 ------------…

AI智能名片B2B2C商城系统:优化三度空间渠道布局与避免渠道冲突的新策略

摘要&#xff1a;在数字化浪潮的推动下&#xff0c;品牌商面临着前所未有的市场挑战与机遇。为了应对这些挑战并抓住机遇&#xff0c;品牌商需要构建并优化一个高效、协同的三度空间&#xff08;线下实体店、线上电商平台、数字营销渠道&#xff09;渠道布局。本文深入探讨了AI…

【多线程-从零开始-玖】内核态,用户态,线程池的参数、使用方法详解

文章目录 1. 为什么会有线程池2. 内核态和用户态2.1 场景构造 3. 标准库的线程池3.1 构造方法的参数3.1.1 核心线程数和最大线程数3.1.2 非核心线程允许摸鱼的最大时间3.1.3 工作队列&#xff08;阻塞队列&#xff09;3.1.4 线程工厂工厂设计模式 3.1.5 拒绝策略四种拒绝策略 3…

极投影ax.contourf

我想用极投影画个类似下面这样的效果图&#xff0c;首先底图是一个这样的&#xff0c;然后再有需要的地方做标记&#xff0c;比如斜线和渔网状的东西。 但是我怎么尝试都是得到了一个下面这样的图这样肯定有问题 我调整为画轮廓线之后变成下面这样的图&#xff0c;我猜想应该是…

Python酷库之旅-第三方库Pandas(073)

目录 一、用法精讲 296、pandas.Series.dt.as_unit方法 296-1、语法 296-2、参数 296-3、功能 296-4、返回值 296-5、说明 296-6、用法 296-6-1、数据准备 296-6-2、代码示例 296-6-3、结果输出 297、pandas.Series.dt.days属性 297-1、语法 297-2、参数 297-3、…

Ansys Mechanical|解决温度场-电场耦合问题

一.多物理场耦合分析的必要性 你是否曾经碰到过你的模型受到两个或者更多物理因素影响的情况吗&#xff1f;这些物理因素不仅会相互影响&#xff0c;还会影响计算结果。 这时多物理场分析就有用了。在解决多物理场影响的工程问题时&#xff0c;多物理场耦合分析是必要的。 举…

IO进程----标准IO

目录 IO进程 标准IO 1. 概念&#xff1a; 2. 特点&#xff1a; 3. 缓存区 3.1. 行缓存&#xff1a;和终端操作相关 刷新缓存的条件&#xff1a; 1) 程序正常退出 2) \n刷新 3) 缓存区满刷新 4) 强制刷新 fflush 3.2. 全缓存&#xff1a;和文件操作相关 3.…

【C++】模版详解

1、概念 C模版分两类&#xff1a;函数模版和类模版 1&#xff09;函数模板的格式 template <class 形参名&#xff0c;class 形参名&#xff0c;......> 返回类型 函数名(参数列表) {函数体 }例如&#xff1a; template <class T> void swap(T& a, T& b…

android13 关闭selinux 临时关闭或者永久关闭

总纲 android13 rom 开发总纲说明 目录 1.前言 2.情况分析 2.1 临时关闭 2.2 永久关闭 3.修改方法 3.1 临时修改 3.2 永久关闭 4.编译测试 5.彩蛋 1.前言 在Android操作系统中,SELinux(Security-Enhanced Linux)是一种安全模块,用于提供强制访问控制(MAC)安全…

为什么不用postman做自动化

面试的时候被问到&#xff1a;为什么不用postman做自动化 打开postman&#xff0c;看到用例集管理、API 管理、环境管理这三个功能&#xff0c;用户体验感算得上品牌等级了 为什么不用呢&#xff0c;文心一言给了一些答案 不适合大规模自动化测试&#xff1a;Postman 主要是为…

AI大模型排行榜(gpt-4o-2024-08-06)

https://github.com/yuchenlin/ZeroEval/blob/main/result_dirs/mmlu-redux.summary.md 人工智能学习网站 https://chat.xutongbao.top

学习日志8.8--防火墙精细化策略管控

本次实验的拓扑结构&#xff0c;用PC2去模拟和外部网络连接的Internet。 在trust和untrust区域上&#xff0c;希望将防火墙安全策略的默认动作修改为deny&#xff0c;然后精细化控制流量的访问&#xff0c;从trust到untrust控制只允许192.168.1.0的网络通过&#xff0c;从untr…

Spring Boot 3.x Filter实战:记录请求日志

上一篇&#xff1a;Spring Boot 3.x Web单元测试最佳实践 前面我们在《Spring Boot 3.x Rest API最佳实践之统一响应结构》中学习响应的统一拦截处理&#xff0c;顺带完成了响应结果的记录&#xff1b;而对于请求内容咱们也必须进行日志记录&#xff0c;以确保排查问题时有据可…

又一苹果经典产品宣布停产,老用户满满的回忆

苹果公司的SuperDrive&#xff0c;作为一项曾经引领潮流的外置光驱技术&#xff0c;自2008年伴随着革命性的MacBook Air轻盈登场以来&#xff0c;便成为了苹果电脑产品线中一道亮丽的风景线&#xff0c;象征着科技与美学的完美结合。 这款光驱以其超薄的设计、高效的读写速度以…

leetcode787. K 站中转内最便宜的航班——优先队列优化的Dijkstra算法+剪枝

题目 leetcode787. K 站中转内最便宜的航班 题目分析 给定一个城市图&#xff0c;每个城市通过航班与其他城市相连。每个航班都有一个起点、终点和价格。你需要找到从起点城市 src 到终点城市 dst 的最便宜路径&#xff0c;但这条路径最多只能经过 k 个中转站。你需要返回这…

构建智能生态,视频监控/安防监控EasyCVR视频汇聚流媒体技术在智能分析领域的应用

随着5G、AI、物联网&#xff08;IoT&#xff09;、云计算等技术的快速发展&#xff0c;万物互联的时代已经到来&#xff0c;全新的行业生态AIoT正在引领一场深刻的变革。在这场变革中&#xff0c;EasyCVR视频流媒体技术以其强大的视频处理、汇聚与融合能力&#xff0c;在智能分…

2024年计算机类学术会议有哪些

随着科技的飞速发展&#xff0c;计算机科学与技术领域正以前所未有的速度进步&#xff0c;各类学术会议成为了交流最新研究成果、探讨前沿技术趋势的重要平台。2024年&#xff0c;全球范围内将举办多场计算机类学术会议&#xff0c;这些会议不仅汇聚了顶尖的专家学者&#xff0…

创客匠人老蒋:你缺的不是客户,缺的是单个客户的营销和变现能力

老蒋创客圈第58期对话标杆直播连麦&#xff0c;我们邀请到【拾才易人】平台创始人侯邦辉老师。侯老师与创客匠人合作3年之久&#xff0c;实现了线上线下高转化&#xff0c;并实现家庭教育、心理疗愈、国学传承与营销运营一站式学习平台。 上篇文章&#xff0c;我们主要梳理了连…

Gemma Scope 帮助理解 AI 模型的内部工作原理

Gemma Scope 工具如何帮助理解 AI 模型&#xff08;具体来说是 Gemma 模型&#xff09;的内部工作原理&#xff0c;通过观察模型的“特征”来理解 AI 是如何“思考”的 1 特征&#xff08;features&#xff09; 了解AI模型在思考什么。Gemma Scope 将 Gemma 模型的大脑分解成…

延时队列与redis and rabbitmq

延时队列是什么 延时队列&#xff08;Delay Queue&#xff09;是一种特殊的消息队列&#xff0c;它允许你在添加消息时设置一个延时时间&#xff0c;消息只有在延时时间到达后才能被消费。这种机制在分布式系统中非常有用&#xff0c;常用于处理需要在指定时间后执行的任务&am…