shiro-hashing algorithm

Meet md5

md5 is an encryption algorithm that protects data security (it has been proven to be not very secure). The md5 encryption algorithm
salt is provided in shiro, which means adding salt. The method of adding salt can further improve the security of data, so in the users table of the database When designing, in addition to id, username, and password , there is also a list of password_salt

//md5加密
		Md5Hash hash=new Md5Hash("123");
		System.out.println(hash.toString());
		//md5加盐
		hash=new Md5Hash("123","wit");
		System.out.println(hash.toString());
		//md5加盐 散列两次,散列次数越多,密码越安全
		hash=new Md5Hash("123","wit",2);
		System.out.println(hash.toString());
		hash=new Md5Hash("456","wit",2);
		System.out.println(hash.toString());
		

To use md5, you must first ensure that the password in the database is encrypted (with tools)
Insert picture description here

Custom realm

After getting the data user ( id, username, password, password_salt ) object from the database , the following line of code is passed to shiro, shiro knows that the required data is encrypted, and there are some parameters, such as the number of hashes, encryption method, and so on. Need to configure realm

SimpleAuthenticationInfo(username,password,ByteSource.Util.bytes(salt),getName());
package cn.wit.realm;

import java.beans.PropertyVetoException;


import java.sql.ResultSet;
import java.sql.SQLException;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;

import cn.wit.users.Users;

import com.mchange.v2.c3p0.ComboPooledDataSource;

import java.sql.Connection;
import java.sql.PreparedStatement;

public class UserRealm extends AuthorizingRealm{
    
    
	@Override
	public String getName() {
    
    
		// TODO Auto-generated method stub
		return "uesrRealm";
	}
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg0) {
    
    
		return null;
	}

	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(
			AuthenticationToken taken) throws AuthenticationException {
    
    
			String username=(String) taken.getPrincipal();
			Users users=null;
			Connection conn=null;
	        PreparedStatement ps=null;
	        ResultSet rs=null;
	        ComboPooledDataSource cpds=null;
	        try {
    
    
	          //c3p0获取数据库连接conn
	    		cpds= new ComboPooledDataSource();
	    		cpds.setDriverClass("com.mysql.jdbc.Driver");
	    		cpds.setJdbcUrl("jdbc:mysql://localhost:3306/login");
	    		cpds.setUser("root");
	    		cpds.setPassword("wityy");
	    		conn = cpds.getConnection();
	            
	            String sql="select *from users where username=?";
	            ps= conn.prepareStatement(sql);
	            ps.setObject(1,username);
	            rs=ps.executeQuery();
	            while(rs.next()){
    
    
	            	users=new Users();
	            	users.setId(rs.getInt("id"));
	            	users.setUsername(rs.getString("username"));
	            	users.setPassword(rs.getString("password"));
	            	users.setPassword_salt(rs.getString("password_salt"));
	            }
	        } catch (SQLException e) {
    
    
	            e.printStackTrace();
	        } catch (PropertyVetoException e) {
    
    
				// TODO Auto-generated catch block
				e.printStackTrace();
			}finally {
    
    
	            try {
    
    
	            	if(rs!=null){
    
    
	            		rs.close();
	            	}
	            } catch (SQLException e) {
    
    
	                e.printStackTrace();
	            }
	            try {
    
    
	            	if(ps!=null){
    
    
	            		ps.close();
	            	}
	            } catch (SQLException e) {
    
    
	                e.printStackTrace();
	            }
	            try {
    
    
	            	if(conn!=null){
    
    
	            		conn.close();
	            	}
	            } catch (SQLException e) {
    
    
	                e.printStackTrace();
	            }
	        }
		
	      username=users.getUsername();
	      String password=users.getPassword();
	      String salt=users.getPassword_salt();
	      System.out.println(username);
	      System.out.println(password);
	      System.out.println(salt);
	      //从数据库中拿到的密码是经过加密的(并且加了盐),所以数据库中才设计盐这个属性,想要解密不仅要拿到密码,还要从数据库拿到盐
	      //除此之外,需要设置realm 告知shiro需要用md5的方式进行解密
	      SimpleAuthenticationInfo info=new 
	    		  SimpleAuthenticationInfo(username,password,ByteSource.Util.bytes(salt),getName());
		
		
		
		return info;
	}

	
}

this

hashAlgorithmName represents the encryption method, hashIterations represents the number of hashes, and credentialsMatcher is a class about setting encryption and assigning it to the realm. There is an introduction at the end of the encrypted source code tracking article

[main]
credentialsMatcher=org.apache.shiro.authc.credential.HashedCredentialsMatcher
credentialsMatcher.hashAlgorithmName=md5
credentialsMatcher.hashIterations=2

userRealm=cn.wit.realm.UserRealm
userRealm.credentialsMatcher=$credentialsMatcher
securityManager.realm=$userRealm

md5 source code tracking

Enter the source code from login, subject implementation class DelegatingSubject, give both itself and taken SecurityManager, implementation class is DefaultSecurityManager, this type of login method calls Authenticator's Authenticator method, enter Authenticator, the implementation class is ModularRealmAuthenticator, there are setRealms, setAuthenticationStrategy, you can proceed Set the authentication strategy and realms, enter the Realm interface, in its implementation class AuthenticatingRealm, there is the credentialsMatcher attribute, which means encryption.
Insert picture description here
View the class hierarchy. There are implementation classes for different decryption methods below.

Insert picture description here
These encryption methods are inherited from HashedCredentialsMatcher, the set method of this class below, we set these attributes in ini, for the protection of salt information, so setting ini only sets the encryption method and the number of hashes. Pass the salt to shiro along with the account password in the custom realm
Insert picture description here

Guess you like

Origin blog.csdn.net/WA_MC/article/details/113564487