The BCryptPasswordEncoder method in Spring security encrypts and matches passwords and the MD5util tool class

Generally record user password, we are all in the form of MD5 encryption configuration. Record here, MD5 encryption tools.

package com.mms.utils;

import java.security.MessageDigest;

/**
 * Created by codermen on 2017/10/26.
 */
public class MD5Util {
    public static void main(String[] args) {
        String pwd = getMD5("99991");
        System.out.println(pwd);
    }

    //生成MD5
    public static String getMD5(String message) {
        String md5 = "";
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");  // 创建一个md5算法对象
            byte[] messageByte = message.getBytes("UTF-8");
            byte[] md5Byte = md.digest(messageByte);              // 获得MD5字节数组,16*8=128位
            md5 = bytesToHex(md5Byte);                            // 转换为16进制字符串
        } catch (Exception e) {
            e.printStackTrace();
        }
        return md5;
    }

    // 二进制转十六进制
    public static String bytesToHex(byte[] bytes) {
        StringBuffer hexStr = new StringBuffer();
        int num;
        for (int i = 0; i < bytes.length; i++) {
            num = bytes[i];
            if(num < 0) {
                num += 256;
            }
            if(num < 16){
                hexStr.append("0");
            }
            hexStr.append(Integer.toHexString(num));
        }
        return hexStr.toString().toUpperCase();
    }
}

Talking about using BCryptPasswordEncoder method in springsecurity to encrypt password (encode) and password match (matches)

The BCryptPasswordEncoder method in spring security uses SHA-256 + random salt + key to encrypt the password. The SHA series is a Hash algorithm, not an encryption algorithm. Using an encryption algorithm means that it can be decrypted (this is the same as encoding / decoding), but with Hash processing, the process is irreversible.

(1) Encryption (encode): When registering a user, use SHA-256 + random salt + key to hash the password entered by the user to obtain the hash value of the password, and then store it in the database.

(2) Password matching (matches): When the user logs in, the password matching stage does not decrypt the password (because the password is hashed and is irreversible), but uses the same algorithm to hash the password entered by the user to obtain the password Hash value, and then compare it with the password hash value queried from the database. If the two are the same, the password entered by the user is correct.

This is why the hash algorithm is used instead of the encryption algorithm when processing passwords. Because in this way, even if the database is leaked, it is difficult for hackers to crack the password (the password can only be used to crack the password).

After learning this, I checked some source code. Take BCryptPasswordEncoder as an example

public class BCryptPasswordEncoderTest {
    public static void main(String[] args) {
        String pass = "admin";
        BCryptPasswordEncoder bcryptPasswordEncoder = new BCryptPasswordEncoder();
        String hashPass = bcryptPasswordEncoder.encode(pass);
        System.out.println(hashPass);

        boolean f = bcryptPasswordEncoder.matches("admin",hashPass);
        System.out.println(f);

    }
}

It can be seen that the hashPass output is different each time, but the final f is true, that is, the match is successful. Looking at the code, you can see that every random salt is actually stored in hashPass. When comparing matches, call BCrypt's String hashpw (String password, String salt) method. Two parameters namely "admin" and hashPass

//******BCrypt.java******salt即取出要比较的DB中的密码*******
real_salt = salt.substring(off + 3, off + 25);
try {
// ***************************************************
    passwordb = (password + (minor >= 'a' ? "\000" : "")).getBytes("UTF-8");
}
catch (UnsupportedEncodingException uee) {}
saltb = decode_base64(real_salt, BCRYPT_SALT_LEN);
B = new BCrypt();
hashed = B.crypt_raw(passwordb, saltb, rounds);

Suppose a hashPass is: 10 $ AxafsyVqK51p.s9WAEYWYeIY9TKEoG83LTEOSB3KUkoLtGsBKhCwe random salt is AxafsyVqK51p.s9WAEYWYe (salt = BCrypt.gensalt (); description
will be seen in Wy. That is, in the encrypted hashPass, the previous part already contains salt information.

If you just want to use SpringSecurity + SpringBoot to complete the password encryption / decryption operation without using other security verification functions provided by SpringSecurty. The specific steps are as follows:
1 BCrypt password encryption
1.1 Preparations For

any application considering security, passwords must never be stored in clear text. The password should be encrypted using a hash algorithm.
There are many standard algorithms such as SHA or MD5, combined with salt (salt) is a good choice. Spring Security
provides the BCryptPasswordEncoder class, which implements Spring's PasswordEncoder interface and uses the BCrypt strong
hash method to encrypt passwords.
The BCrypt strong hash method has different encryption results every time.
(1) The introduction of the pom of the tensquare_user project depends on

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring‐boot‐starter‐security</artifactId>
</dependency>

(2) Add configuration class (provided in resource / tool class)

After we added the spring security dependency, all the addresses are controlled by spring security. At present, we
only need to use the BCrypt password encryption part, so we need to add a configuration class that is configured so that all addresses
can be accessed anonymously.

/**
* 安全配置类
*/
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter{
@Override
protected void configure(HttpSecurity http) throws Exception {
    http
      .authorizeRequests()
      .antMatchers("/**").permitAll()
      .anyRequest().authenticated()
      .and().csrf().disable();
  }
}

(3) Modify the Application and configuration beans of the tensquare_user project

@Bean
public BCryptPasswordEncoder bcryptPasswordEncoder(){
return new BCryptPasswordEncoder();
}

After that, you can use the methods in BCryptPasswordEncoder to complete the encryption / decryption operation:

加密:
bcryptPasswordEncoder.encoder(password)
解密:
bcrytPasswordEncoder.matches(rawPassword,encodedPassword)
Published 17 original articles · Likes0 · Visits 224

Guess you like

Origin blog.csdn.net/weixin_42531204/article/details/105254213