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)
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.
View the class hierarchy. There are implementation classes for different decryption methods below.
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