• Spring中加密工具类DigestUtils和BCryptPasswordEncoder


    spring中的加密工具类DigestUtils

    Spring中自带了一个加密工具类,所在的位置的是org.springframework.util.DigestUtils,在spring-core模块中。
    该工具类中默认只提供了MD5加密相关的静态方法,同时还有一些获取其他加密算法的私有方法(暗示了我们开发者可以通过继承此工具类,来实现对任意加密算法的实现)

    在此工具类的解释中,是这样说的:
    “Miscellaneous methods for calculating digests.Mainly for internal use within the framework; consider Apache Commons Codec for a more comprehensive suite of digest utilities.”
    意思是说:“这个工具类提供了计算摘要的各种方法。主要用于框架内部使用;如果想要获得更全面的摘要实用程序套件,请考虑Apache Commons Codec。”
    也就是说,spring提供这个加密工具类的初衷是供框架内部使用,这个类是在Apache Commons Codec的基础上建立的,所以我们想要更全面的加密工具,还需要访问Apache Commons Codec。(Apache Commons Codec模块提供了对数据进行编码、解码的一系列方法,例如Base64、Hex等)

    请注意,现在MD5加密不能保证绝对安全,因此在使用MD5加密时,最后在数据库中维护一个盐值salt,利用此盐值为明文进行加密
    MD5本质是基于Hash来做的,是不可逆的

    BCryptPasswordEncoder

    Spring Security中提供了一个密码加密的工具,org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder
    采用SHA-256 +随机盐+密钥对密码进行加密。SHA系列是Hash算法,不是加密算法,使用加密算法意味着可以解密(这个与编码/解码一样),但是采用Hash处理,其过程是不可逆的。

    BCryptPasswordEncoder中常用的方法

    • encode(String password)对明文加密,返回生成的密文
    • matches(plainText, encodedText)明文与密文进行比配,返回true或false

    我们使用BCryptPasswordEncoder类来加密时,无需在数据库中再维护一个盐值salt
    BCryptPasswordEncoder在加密时,会随机生成一个盐值salt

    即使相同的明文,两次加密后的结果也是不一样的

    BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
    String password = "root";
    System.out.println(encoder.encode(password));
    System.out.println(encoder.encode(password));
    
    • 1
    • 2
    • 3
    • 4

    加密结果:

    $2a$10$rIWmomm6VnvBFjuOaF1VT.Pje87EsxaMxpFcPn7D1IXWUVBK05ne6
    $2a$10$.4HVn5lws4y/BLhFrefYauvSth3REk/yjXjP/TBLnF7l//q3Oz7aO
    
    • 1
    • 2

    即使两次的密文是不同的,但是与明文进行匹配时,确实都是可以成功的。

    BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
    String password = "root";
    String encodedPwd1 = "$2a$10$rIWmomm6VnvBFjuOaF1VT.Pje87EsxaMxpFcPn7D1IXWUVBK05ne6";
    String encodePwd2 = "$2a$10$.4HVn5lws4y/BLhFrefYauvSth3REk/yjXjP/TBLnF7l//q3Oz7aO";
    System.out.println(encoder.matches("root", encodedPwd1));
    System.out.println(encoder.matches("root", encodePwd2));
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    结果是

    true
    true
    
    • 1
    • 2

    大致的原理就是:虽然两次的密文不同,但是能从密文中获取到使用的盐值salt,重新利用此salt和明文进行加密,得到的结果是否是密文,因此得证:虽然两次密文不同,但是都可以与明文匹配成功。

    参考文档

    springboot学习——MD5加密
    BCryptPasswordEncoder的使用及原理_码农UP2U的博客-CSDN博客

  • 相关阅读:
    告别EXCEL,易点易动库存管理系统帮助企业提升固定资产管理效率
    MyBatis--逆向工程
    MM-Camera架构-Preview 流程分析
    Keil代码自动排版配置工具AStyle
    使用PWM实现呼吸灯功能
    macOS Sonoma 14.1正式版发布 改善Apple Music界面 新增保修状态显示
    请你说说Spring
    需求可追溯性的四个最佳实践
    手记系列之二 ----- 关于IDEA的一些使用方法经验
    从零学习 InfiniBand-network架构(八) —— IB协议中的原子操作
  • 原文地址:https://blog.csdn.net/weixin_55697693/article/details/132822912