Md5+salt实现用户加密

Posted 健康平安的活着

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Md5+salt实现用户加密相关的知识,希望对你有一定的参考价值。

一.md5

1.1 作用

一般用来进行加密或者签名

特点:md5内容不可逆,相同的内容不论执行多少次,md5加密算法生成的结果都是一致的。

结果:生成的结果是一个32位的16进制字符串。

二 md5+salt

salt说白了就是随机的字符串

2.1 md5+salt的使用

注册时md5(输入明文密码+随机盐字符串)生成加密密码p1,随机盐字符串r,都存储到数据库中。

登录时通过用户名查询该用户对应的加密密码p1和随机盐字符串r,按照注册时生成的规则:md5(输入明文密码+随机盐字符串)=p2,

这次登录生成的新的加密字符串p2和从数据库查询出的加密字符串p1进行比较判断。相同则密码正确,否则错误。

 

三  md5+salt+hash散列案例

3.1 加密

package com.shiro.ljf.demo.test;

import org.apache.shiro.crypto.hash.Md5Hash;

public class TestShiroMD5 {
    public static void main(String[] args) {

        //创建一个md5算法
//        Md5Hash md5Hash = new Md5Hash();
//        md5Hash.setBytes("123".getBytes());
//        String s = md5Hash.toHex();
//        System.out.println(s);

        //使用md5
        Md5Hash md5Hash = new Md5Hash("123");

        System.out.println(md5Hash.toHex());

        //使用MD5 + salt处理
        Md5Hash md5Hash1 = new Md5Hash("123", "X0*7ps");

        System.out.println(md5Hash1.toHex());

        //使用md5 + salt + hash散列
        Md5Hash md5Hash2 = new Md5Hash("123", "X0*7ps", 1024);
        System.out.println(md5Hash2.toHex());


    }
}

结果:

202cb962ac59075b964b07152d234b70
8a83592a02263bfe6752b2b5b03a4799
e4f9bf3e0c58f045e62c23c533fcf633

3.2 使用salt+md5+hash散列

package com.shiro.ljf.demo.test;

import com.shiro.ljf.demo.sptshirodemo.shiro.CustomerMd5Realm;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.subject.Subject;

import java.util.Arrays;

public class TestCustomerMd5RealmAuthenicator {

    public static void main(String[] args) {

        //创建安全管理器
        DefaultSecurityManager defaultSecurityManager = new DefaultSecurityManager();
        //注入realm
        CustomerMd5Realm realm = new CustomerMd5Realm();
        //设置realm使用hash凭证匹配器

        HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher();
        //使用算法
        credentialsMatcher.setHashAlgorithmName("md5");
        //散列次数
        credentialsMatcher.setHashIterations(1024);
        realm.setCredentialsMatcher(credentialsMatcher);

        defaultSecurityManager.setRealm(realm);
        //将安全管理器注入安全工具
        SecurityUtils.setSecurityManager(defaultSecurityManager);

        //通过安全工具类获取subject
        Subject subject = SecurityUtils.getSubject();

        //认证
        UsernamePasswordToken token = new UsernamePasswordToken("lisi", "123");

        try {
            subject.login(token);
            System.out.println("登录成功");
        } catch (UnknownAccountException e) {
            e.printStackTrace();
            System.out.println("用户名错误");
        }catch (IncorrectCredentialsException e){
            e.printStackTrace();
            System.out.println("密码错误");
        }


        //授权
        if(subject.isAuthenticated()){
        }

    }
}

自定义reaml:

package com.shiro.ljf.demo.sptshirodemo.shiro;

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.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;

/**
 * 使用自定义realm 加入md5 + salt +hash
 */
public class CustomerMd5Realm extends AuthorizingRealm {

    //授权
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        String primaryPrincipal = (String) principals.getPrimaryPrincipal();
        System.out.println("身份信息: "+primaryPrincipal);

        //根据身份信息 用户名 获取当前用户的角色信息,以及权限信息  xiaochen  admin user
        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();

        //将数据库中查询角色信息赋值给权限对象
        simpleAuthorizationInfo.addRole("admin");
        simpleAuthorizationInfo.addRole("user");

        //将数据库中查询权限信息赋值个权限对象
        simpleAuthorizationInfo.addStringPermission("user:*:01");
        simpleAuthorizationInfo.addStringPermission("product:create");


        return simpleAuthorizationInfo;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        //获取身份信息
        String principal = (String) token.getPrincipal();

        //根据用户名查询数据库
        if ("lisi".equals(principal)) {
            //参数1: 数据库用户名  参数2:数据库md5+salt之后的密码  参数3:注册时的随机盐  参数4:realm的名字
            //用户输入的密码+加上从数据库获取的盐,生成新的加密串,和从数据库加载的串进行比较,这个动作就是在shiro底层自动完成的,这里只需要在
            //SimpleAuthenticationInfo设置好对应的参数就行。
            return new SimpleAuthenticationInfo(principal,
                    "e4f9bf3e0c58f045e62c23c533fcf633",
                    ByteSource.Util.bytes("X0*7ps"),
                    this.getName());
        }
        return null;
    }
}

3.3 执行结果:

 

以上是关于Md5+salt实现用户加密的主要内容,如果未能解决你的问题,请参考以下文章

如何为一个密码实现sha 512,md5和salt加密[重复]

salt值(盐值)

关于MD5+salt盐加密

MD5+salt的加密

ecshop教程:重置后台密码MD5+salt

常见用户密码加密方式之特殊的单向HASH算法