Spring Security’s PasswordEncoder interface is used to support the use of passwords which are encoded in some way in persistent storage. You should never store passwords in plain text. Always use a one-way password hashing algorithm such as bcrypt which uses a built-in salt value which is different for each stored password. Do not use a plain hash function such as MD5 or SHA, or even a salted version. Bcrypt is deliberately designed to be slow and to hinder offline password cracking, whereas standard hash algorithms are fast and can easily be used to test thousands of passwords in parallel on custom hardware. You might think this doesn’t apply to you since your password database is secure and offline attacks aren’t a risk.

Spring Security的PasswordEncoder接口用于支持使用在持久存储中以某种方式编码的密码。您绝不应以纯文本格式存储密码。始终使用单向密码散列算法,例如bcrypt,它使用内置的salt值,该值对于每个存储的密码是不同的。不要使用普通的哈希函数,如MD5或SHA,甚至是盐渍版本。 Bcrypt被故意设计为缓慢并阻碍脱机密码破解,而标准哈希算法很快,可以很容易地用于在自定义硬件上并行测试数千个密码。您可能认为这不适用于您,因为您的密码数据库是安全的,并且脱机攻击不存在风险。
 
If so, do some research and read up on all the high-profile sites which have been compromised in this way and have been pilloried for storing their passwords insecurely. It’s best to be on the safe side. Using org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder" is a good choice for security. There are also compatible implementations in other common programming languages so it a good choice for interoperability too.
如果是这样的话,做一些研究并阅读所有以这种方式受到损害的高知名度的网站,并因为不安全地存储密码而受到嘲笑。最好是安全起见。使用org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder“是一个很好的安全选择。在其他常见的编程语言中也有兼容的实现,因此它也是互操作性的一个很好的选择。
 
If you are using a legacy system which already has hashed passwords, then you will need to use an encoder which matches your current algorithm, at least until you can migrate your users to a more secure scheme (usually this will involve asking the user to set a new password, since hashes are irreversible). Spring Security has a package containing legacy password encoding implementation, namely, org.springframework.security.authentication.encoding. The DaoAuthenticationProvider can be injected with either the new or legacy PasswordEncoder types.
如果您使用的是已经具有散列密码的旧系统,那么您将需要使用与当前算法匹配的编码器,至少在您将用户迁移到更安全的方案之前(通常这将涉及要求用户设置)一个新密码,因为哈希是不可逆转的)。 Spring Security有一个包含传统密码编码实现的包,即org.springframework.security.authentication.encoding。可以使用新的或旧的PasswordEncoder类型注入DaoAuthenticationProvider。

10.3.1 What is a hash?

Password hashing is not unique to Spring Security but is a common source of confusion for users who are not familiar with the concept. A hash (or digest) algorithm is a one-way function which produces a piece of fixed-length output data (the hash) from some input data, such as a password. As an example, the MD5 hash of the string "password" (in hexadecimal) is

密码散列并非Spring Security独有,但却是不熟悉该概念的用户常见的混淆源。散列(或摘要)算法是单向函数,其从一些输入数据(例如密码)产生一段固定长度的输出数据(散列)。例如,字符串“password”(十六进制)的MD5哈希值是
 
5f4dcc3b5aa765d61d8327deb882cf99

A hash is "one-way" in the sense that it is very difficult (effectively impossible) to obtain the original input given the hash value, or indeed any possible input which would produce that hash value. This property makes hash values very useful for authentication purposes. They can be stored in your user database as an alternative to plaintext passwords and even if the values are compromised they do not immediately reveal a password which can be used to login. Note that this also means you have no way of recovering the password once it is encoded.

在某种意义上,散列是“单向的”,即在给定散列值的情况下获得原始输入是非常困难的(实际上是不可能的),或者实际上任何可能产生该散列值的输入。此属性使哈希值对于身份验证非常有用。它们可以存储在您的用户数据库中,作为明文密码的替代方法,即使这些值被泄露,它们也不会立即显示可用于登录的密码。请注意,这也意味着您无法在编码后恢复密码。

10.3.2 Adding Salt to a Hash

One potential problem with the use of password hashes that it is relatively easy to get round the one-way property of the hash if a common word is used for the input. People tend to choose similar passwords and huge dictionaries of these from previously hacked sites are available online. For example, if you search for the hash value 5f4dcc3b5aa765d61d8327deb882cf99 using google, you will quickly find the original word "password". In a similar way, an attacker can build a dictionary of hashes from a standard word list and use this to lookup the original password.

使用密码哈希的一个潜在问题是,如果将常用字用于输入,则相对容易绕过哈希的单向属性。人们倾向于选择类似的密码,并且可以在线获取以前被黑客攻击的网站中的大量字典。例如,如果使用谷歌搜索哈希值5f4dcc3b5aa765d61d8327deb882cf99,您将很快找到原始单词“password”。以类似的方式,攻击者可以从标准单词列表构建哈希字典,并使用它来查找原始密码。
 
One way to help prevent this is to have a suitably strong password policy to try to prevent common words from being used. Another is to use a "salt" when calculating the hashes. This is an additional string of known data for each user which is combined with the password before calculating the hash. Ideally the data should be as random as possible, but in practice any salt value is usually preferable to none. Using a salt means that an attacker has to build a separate dictionary of hashes for each salt value, making the attack more complicated (but not impossible).
一种有助于防止这种情况的方法是使用适当强大的密码策略来尝试防止使用常用词。另一种是在计算哈希时使用“盐”。这是每个用户的附加字符串,在计算哈希值之前与密码组合。理想情况下,数据应尽可能随机,但实际上任何盐值通常都优于无。使用salt意味着攻击者必须为每个salt值构建一个单独的哈希字典,使攻击更加复杂(但并非不可能)。
 
Bcrypt automatically generates a random salt value for each password when it is encoded, and stores it in the bcrypt string in a standard format.
Bcrypt在编码时自动为每个密码生成一个随机盐值,并以标准格式将其存储在bcrypt字符串中。
 

The legacy approach to handling salt was to inject a SaltSource into the DaoAuthenticationProvider, which would obtain a salt value for a particular user and pass it to the PasswordEncoder. Using bcrypt means you don’t have worry about the details of salt handling (such as where the value is stored), as it is all done internally. So we’d strongly recommend you use bcrypt unless you already have a system in place which stores the salt separately.

处理salt的传统方法是将SaltSource注入DaoAuthenticationProvider,它将获取特定用户的salt值并将其传递给PasswordEncoder。使用bcrypt意味着您不必担心盐处理的细节(例如存储值的位置),因为它都是在内部完成的。所以我们强烈建议您使用bcrypt,除非您已经有一个系统可以单独存储盐。
 

10.3.3 Hashing and Authentication

When an authentication provider (such as Spring Security’s DaoAuthenticationProvider) needs to check the password in a submitted authentication request against the known value for a user, and the stored password is encoded in some way, then the submitted value must be encoded using exactly the same algorithm. It’s up to you to check that these are compatible as Spring Security has no control over the persistent values. If you add password hashing to your authentication configuration in Spring Security, and your database contains plaintext passwords, then there is no way authentication can succeed. Even if you are aware that your database is using MD5 to encode the passwords, for example, and your application is configured to use Spring Security’s Md5PasswordEncoder, there are still things that can go wrong.

当身份验证提供程序(例如Spring Security的DaoAuthenticationProvider)需要针对用户的已知值检查提交的身份验证请求中的密码,并且以某种方式对存储的密码进行编码时,必须使用完全相同的方式对提交的值进行编码算法。由您决定这些是否兼容,因为Spring Security无法控制持久值。如果在Spring Security中为您的身份验证配置添加密码哈希,并且您的数据库包含明文密码,那么身份验证就无法成功。例如,即使您知道数据库使用MD5对密码进行编码,并且您的应用程序配置为使用Spring Security的Md5PasswordEncoder,仍然可能出现问题。
 
The database may have the passwords encoded in Base 64, for example while the encoder is using hexadecimal strings (the default). Alternatively your database may be using upper-case while the output from the encoder is lower-case. Make sure you write a test to check the output from your configured password encoder with a known password and salt combination and check that it matches the database value before going further and attempting to authenticate through your application. Using a standard like bcrypt will avoid these issues.
数据库可能具有以Base 64编码的密码,例如,当编码器使用十六进制字符串(默认值)时。或者,您的数据库可能使用大写,而编码器的输出是小写的。确保编写测试以使用已知密码和salt组合检查已配置密码编码器的输出,并在进一步尝试通过应用程序进行身份验证之前检查它是否与数据库值匹配。使用像bcrypt这样的标准可以避免这些问题。
 
If you want to generate encoded passwords directly in Java for storage in your user database, then you can use the encode method on the PasswordEncoder.
如果要直接在Java中生成编码密码以存储在用户数据库中,则可以在PasswordEncoder上使用encode方法。
 

Spring Security(三十三):10.3 Password Encoding的更多相关文章

  1. 使用Spring Security Oauth2完成RESTful服务password认证的过程

            摘要:Spring Security与Oauth2整合步骤中详细描述了使用过程,但它对于入门者有些重量级,比如将用户信息.ClientDetails.token存入数据库而非内存.配置 ...

  2. Spring Security(三) —— 核心配置解读

    摘要: 原创出处 https://www.cnkirito.moe/spring-security-3/ 「老徐」欢迎转载,保留摘要,谢谢! 3 核心配置解读 上一篇文章<Spring Secu ...

  3. Spring Security(十三):5.2 HttpSecurity

    Thus far our WebSecurityConfig only contains information about how to authenticate our users. How do ...

  4. Spring Security三种认证

    Spring Security: 1.用户名+密码认证 2.手机号+短信认证 Spring Social: 1.第三方认证, QQ登录等 Spring Security OAuth: 1.把认证之后的 ...

  5. spring security 学习文档

    web service Prepared by:   Sea                                                                       ...

  6. SpringBoot集成Spring Security入门体验

    一.前言 Spring Security 和 Apache Shiro 都是安全框架,为Java应用程序提供身份认证和授权. 二者区别 Spring Security:重量级安全框架 Apache S ...

  7. Spring Security(七):2.4 Getting Spring Security

    You can get hold of Spring Security in several ways. You can download a packaged distribution from t ...

  8. Spring Security(三十二):10. Core Services

    Now that we have a high-level overview of the Spring Security architecture and its core classes, let ...

  9. Spring Security(三十四):10.4 Jackson Support

    Spring Security has added Jackson Support for persisting Spring Security related classes. This can i ...

随机推荐

  1. LocalDateTime反序列化,LocalDateTime格式化

    使用mybatis-plus的时候出现了LocalDateTime类(jdk8 中新出现的类 那么我在反序列化的时候出了问题. 我在springboot 2.1.3 中使用以下类结局问题) 用到了下面 ...

  2. JavaScript与WebAssembly进行比较

    本文由云+社区发表 作者:QQ音乐前端团队 在识别和描述核心元素的过程中,我们分享了构建SessionStack时使用的一些经验法则,这是一个轻量级但健壮且高性能的JavaScript应用程序,以帮助 ...

  3. Servlet+Tomcat总结

    Tomcat的缺省端口是多少,怎么修改 1.找到Tomcat目录下的conf文件夹 2.进入conf文件夹里面找到server.xml文件 3.打开server.xml文件 4.在server.xml ...

  4. Magicodes.NET框架之路——V0.0.0.5 Beta版发布

    最近写代码的时间实在不多,而且今年又打算业余学习下Unity3D以及NodeJs(用于开发游戏后台),因此完善框架的时间更不多了.不过我会一直坚持下去的,同时我也希望有兴趣的同学可以加入Push你的代 ...

  5. Spring Cloud Alibaba与Spring Boot、Spring Cloud之间不得不说的版本关系

    这篇博文是临时增加出来的内容,主要是由于最近连载<Spring Cloud Alibaba基础教程>系列的时候,碰到读者咨询的大量问题中存在一个比较普遍的问题:版本的选择.其实这类问题,在 ...

  6. C#程序员知识体系

    [https://blog.csdn.net/zj735539703/article/details/50409476] 基础部分 C# 基础语法 OOP的概念,面向对象的理解 继承 封装 多态 AS ...

  7. 分享PowerDesigner使用的设置

    用PowerDesigner比较直观, 方便管理,修改数据库,分享 Oracle的逆向工程,和模型图的显示设置 https://blog.csdn.net/u011781521/article/det ...

  8. Djiango初识

    加载静态文件 在一个网页中,不仅仅只有一个 html 骨架,还需要 css 样式文件, js 执行文件以及一些图片 等.因此在 DTL 中加载静态文件是一个必须要解决的问题.在 DTL 中,使用 st ...

  9. 20190322-a标签、img标签、三列表、特殊字符实体、表格

    目录 1.a标签 a标签的属性 锚点 2.img标签 img标签的属性 图像热区 3.三列表 有序列表(Ordered List)     ol>li 无序列表(Unordered List)  ...

  10. jsp基础语言-jsp表达式

    1.jsp表达式作用:将动态信息显示在页面中. 2.jsp表达式语法:<%=变量或表达式%> 变量:要在页面显示的值的变量名 表达式:其值由服务器计算,计算结果以字符串的形式发送到客户端 ...