Shiro Learning - MD5 Encryption and Salt Value

Preface

The previous article described how shiro configures encryption services. This article uses the md5 encryption algorithm as an example. The md5 algorithm is a common encryption algorithm, and salt is often added to improve security. How do these configurations work is shown in this article.

What is the salt value?

Encrypts like MD5 have the same password for the same password. If we initialize the system and set the password for all users to 123 456, then all encrypted text will be the same after MD5 encryption. As long as the stealer cracks the encrypted text, all accounts with the same encrypted text will be stolen. How can we avoid this? Salt.The operation is to stitch together the salt (actually a small string, such as abc) and the plain text to encrypt during the plain text encryption process. Because each account has different salt values, the plain text and the encrypted ciphertext are different, so the account security is greatly improved.

Configure User Account Password

Initially, I was ready to put the username account number in the form of ini file, but I haven't been able to do so for a long time. Check the source code, because IniRealm reads the ini file's account password without the ability to read salt values, and the SimpleAccount class used to store authentication information does not contain salt values. So if the reader wants to use ini file for account password managementI have to override some of the methods of this class. Because of the difficulty, I have given up this route.

I chose to use the database configuration account password form so that the default JdbcRealm is to support cryptographic storage with salt values.See the first article in this series, " Shiro Learning (1) - Shiro Configuration and Quick Start The password_salt of the default users table is used to store salt values, as shown in the following figure.

 

Next we write a method to generate encrypted ciphertext and salt values. Here we pass in 123 as the password, abcd as the salt value, and md5 as the encryption algorithm for 10 encryption iterations:

public void encryptMD5(String password) {
	System.out.println("Encrypted salt value:"+Base64.encodeToString("abcd".getBytes()));
	SimpleHash hash = new SimpleHash("md5", password, "abcd", 10);	
	System.out.println("Encrypted password:"+hash.toString());
}

Execute this code and output the result:

Since JdbcRealm decrypts salt values by default as Base64, we should write the encrypted salt values to the database as follows:

This completes the preparation

Initialize configuration and test

Next, we test the validity of the authentication by configuring the database. Write the following code:

public static void main(String[] args) throws Exception {
	DefaultSecurityManager securityManager = new DefaultSecurityManager();
	JdbcRealm realm = new JdbcRealm();
	Class<DruidDataSource> clazz = DruidDataSource.class;
	DruidDataSource dataSource = clazz.newInstance();
	dataSource.setUsername("root");
	dataSource.setPassword("");
	dataSource.setUrl("jdbc:mysql://localhost:3306/shiro");
	dataSource.setDriverClassName("com.mysql.jdbc.Driver");
	realm.setDataSource(dataSource);
	realm.setPermissionsLookupEnabled(true);
	
	HashedCredentialsMatcher cm = new HashedCredentialsMatcher();
	cm.setHashAlgorithmName("md5");
	cm.setHashIterations(10);
	realm.setCredentialsMatcher(cm);
	realm.setSaltStyle(SaltStyle.COLUMN);
	
	securityManager.setRealm(realm);
	SecurityUtils.setSecurityManager(securityManager);
	Subject subject = SecurityUtils.getSubject();
	
	UsernamePasswordToken token = new UsernamePasswordToken("zhang", "123");
	try {
		subject.login(token);
		System.out.println("ok");
	} catch (AuthenticationException e) {
		e.printStackTrace();
	}
	subject.logout();
}

Lines 2-11 are the code to configure the database connection, which is not detailed in the previous article. Lines 13-17 are the key to matching passwords. Shiro Learning (5) - Encryption and Decryption of Password "As we have said, one of the key points in password matching is the implementation class of the CredentialsMatcher interface. Because we use MD5 encryption this time, we use the HashedCredentialsMatcher class to accompany. 14 lines set the encryption algorithm to md5, 15 lines set the iteration number to 10 times, which is consistent with how we previously encrypted. 16 lines configure HashedCredentialsMatcher to jdbcRealIn m, jdbcRealm calls HashedCredentialsMatcher when it needs to match the password of the account number. Seventeen rows set the salt mode to SaltStyle.COLUMN. By default, SaltStyle.NO_SALT does not add salt.

Execute the code and output ok if there are no other exceptions. If the error in the following figure is reported, the account password does not match. This situation requires checking that the account password is configured correctly, that the salt value is encrypted, and that SaltStyle.COLUMN is set as the salt value encryption method.

If it still cannot be found, go to the doCredentialsMatch method of org.apache.shiro.authc.credential.HashedCredentialsMatcher to see if the incoming token (information submitted by the user) and info (information obtained from the database) have problems and find out where the problem is.

Summary

This part is not complicated, but I have been stuck with ini file configuration for a long time and with base64 encryption for salt value. Later, it needs to be debugged by tracing the source code to understand. Most of the articles I find on the Internet are copied from it, basically by customizing a realm, and also by writing the salt value of the account password in it.It's still a hassle to transform. With such a simple business function shiro already available, there's no need to expand or customize anything.

Tags: Java Shiro

Posted on Sat, 25 Sep 2021 13:04:02 -0400 by Pointybeard