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. nodejs操作session和cookie

    session: 安装模块 cnpm install express-session 引入session注册到路由 var express = require('express'); var sess ...

  2. Java开发知识之XML文档使用,解析

    目录 XML文件详解 一丶XML简介 1.文档结构 2.XML中的元素(Element)或者叫做标签(Tab).属性 文本内容. 节点(Node) 3.XML语法规则 二丶XML文档解析 三丶使用XP ...

  3. 流式大数据计算实践(5)----HBase使用&SpringBoot集成

    一.前言 1.上文中我们搭建好了一套HBase集群环境,这一文我们学习一下HBase的基本操作和客户端API的使用 二.shell操作 先通过命令进入HBase的命令行操作 /work/soft/hb ...

  4. 简单了解http协议-1

    一.概述 1.了解web及网络基础 1.1.使用http协议访问web,web页面是如何呈现的? 1.2.什么是HTTP,概念及特性 1).HTTP协议是Hyper Text Transfer Pro ...

  5. JS闭包作用域解析

    什么是闭包? 简单理解,当在一个函数的外部访问函数内部定义的变量的时候就会形成一个闭包,由这个理解可以知道,当一个函数执行完成的时候,一般情况下,其作用域会被销毁,其内部定义的变量也会变得不可访问,所 ...

  6. C#在截屏时将截屏之前需要隐藏的控件也截入

    最近我在项目中遇到一个让我十分头疼的问题,就是我在截屏时也将截屏之前隐藏的控件也截入了. 情况:我在Winform窗体有个截屏功能按钮,实现在调用WPF全屏后截屏,但在截屏WPF界面前将界面里的一个L ...

  7. php 爬虫框架

    发现两款不错的爬虫框架,极力推荐下: phpspider 一款优秀的PHP开发蜘蛛爬虫 官方下载地址:https://github.com/owner888/phpspider 官方开发手册:http ...

  8. PHP中private、public、protected的区别详解

    先简单粗俗的描述下:public 表示全局,类内部外部子类都可以访问:private表示私有的,只有本类内部可以使用:protected表示受保护的,只有本类或子类或父类中可以访问: 再啰嗦的解释下: ...

  9. Android开发——Notification通知的使用及NotificationCopat.Builder常用设置API

    想要看全部设置的请看这一篇 [转]NotificationCopat.Builder全部设置 常用设置: 设置属性 说明 setAutoCancel(boolean autocancel) 设置点击信 ...

  10. SpringBoot 整合 apollo

    简介 Apollo(阿波罗)是携程框架部门研发的分布式配置中心,能够集中化管理应用不同环境.不同集群的配置,配置修改后能够实时推送到应用端,并且具备规范的权限.流程治理等特性,适用于微服务配置管理场景 ...