Small knowledge, big challenge! This paper is participating in theEssentials for programmers”Creative activities.
Writing in the front
Through the previous few chapters. We have a general understanding of Security’s user authentication system, which is the foundation.
The process of user authentication usually involves password verification, so password security is also a core issue that we need to consider. Spring Security is a fully functional Security framework. On the one hand, it provides PasswordEncoder components for authentication operations, and on the other hand, it also contains an independent and complete encryption module
One more word, welcome to click on my avatar, to view my column, we learn together!! The design patterns topic has been completed, and the Security and concurrent queues columns will be completed next.
PasswordEncoder
In the previous article, we also introduced a database-based storage scheme for user information. Let’s look at the following code:
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.jdbcAuthentication().dataSource(dataSource)
.usersByUsernameQuery("select username, password, enabled from Users " + "where username=?")
.authoritiesByUsernameQuery("select username, authority from UserAuthorities " + "where username=?")
.passwordEncoder(new BCryptPasswordEncoder());
}
Copy the code
Note that in the above method, we must integrate encryption when authenticating user information through the jdbcAuthentication() method, that is, using the passwordEncoder() method to embed an implementation class of the passwordEncoder interface.
PasswordEncoder interface
In Spring Security, the PasswordEncoder interface represents a cipher encoder. Its core role is to specify the specific encryption method of the password and how to match a given encrypted string with the plaintext. The PasswordEncoder interface is defined as follows:
public interface PasswordEncoder {
// Encode the original password
String encode(CharSequence rawPassword);
// Compare the submitted original password with the encrypted password stored in the library
boolean matches(CharSequence rawPassword, String encodedPassword);
// Checks whether the encryption password needs to be encrypted again. False is returned by default
default boolean upgradeEncoding(String encodedPassword) {
return false; }}Copy the code
Spring Security comes with a number of built-in implementation classes for the PasswordEncoder interface, as shown below:
Let’s expand on some of the more common PasswordEncoder interfaces shown above.
-
NoOpPasswordEncoder: Retain the password in plain text without encoding the password. This PasswordEncoder is usually only used for demonstration purposes and should not be used in production environments.
-
StandardPasswordEncoder: Hash the password using the SHA-256 algorithm.
-
BCryptPasswordEncoder: Hashes passwords using the Bcrypt strong hash algorithm.
-
Pbkdf2PasswordEncoder: Hashed the password using the PBKDF2 algorithm.
Let’s take BCryptPasswordEncoder as an example and look at its encode method, as shown below:
public String encode(CharSequence rawPassword) {
String salt;
if(random ! =null) {
salt = BCrypt.gensalt(version.getVersion(), strength, random);
} else {
salt = BCrypt.gensalt(version.getVersion(), strength);
}
return BCrypt.hashpw(rawPassword.toString(), salt);
}
Copy the code
As you can see, the encode method above performs two steps, first generating the Salt using the BCrypt utility class provided by Spring Security, and then generating the final ciphertext password from the Salt and the plaintext password. It is necessary to expand the concept of salting: when the plaintext is initialized, the system automatically adds some additional data to the plaintext and hashes it. The salting mechanism is introduced to further ensure the security of encrypted data. Unidirectional hash encryption and salting are also widely used in password generation and verification during system login.
Similarly, in Pbkdf2PasswordEncoder, the password is hashed with salt, and the result is hashed with the password again as salt. The process is repeated many times to generate the final ciphertext.
Having introduced the basic structure of PasswordEncoder, let’s move on to how it can be used. If we want to use one of the PasswordEncoder implementation classes in our application, we usually just create an instance of it through its constructor, for example:
PasswordEncoder p = new StandardPasswordEncoder();
PasswordEncoder p = new StandardPasswordEncoder("secret");
PasswordEncoder p = new SCryptPasswordEncoder();
PasswordEncoder p = new SCryptPasswordEncoder(16384.8.1.32.64);
Copy the code
If you want to use NoOpPasswordEncoder, in addition to the constructor, you can also use its getInstance() method to get a static instance, as shown below:
PasswordEncoder p = NoOpPasswordEncoder.getInstance()
Copy the code
conclusion
Well, that’s all for today. Today, the reason why we talk about this encryption technology is mainly for the following reasons:
For a Web application, once user authentication needs to be realized, it is bound to involve the encryption of user password and other sensitive information. For this purpose, Spring Security provides the PasswordEncoder component to encrypt and decrypt passwords. Spring Security has a set of plug-and-play PasswordEncoder built in, and through the proxy mechanism to achieve version compatibility and unified management of each component. This kind of design idea is also worth our study and reference.
Next time we’ll learn how to customize encryption. See you next time
Thank you for reading, if you feel that you have learned something, please like, follow. Also welcome to have a question we comment below exchange
Come on! See you next time!
To share with you a few I wrote in front of a few SAO operation
Talk about different strategy patterns (Bookmarks)
Copy object, this operation is a little SAO!