MD5加盐源码理解

1.shiro中主要的类

简单看一下即可,shiro是一个安全验证框架,相对Spring security使用更为简单。本篇文章使用的的md5加密和加盐是基于shiro框架。
复制代码

 主要功能:认证,授权,加密,会话管理等


2.MD5中的加盐

所谓加盐:如果直接通过md5进行加密,如果别人知道你的密码散列值,通过查找散列值字典,就可以破译密码。而“加盐”,是当用户注册的时候提供密码,然后由系统里往密码加盐,然后再散列加密。这个盐的值是系统随机生成,只有系统知道,这样,即使两个用户注册时使用了同一个密码,它们存储在数据库中的散列值是不一样的。这个方法下,密码的安全性更高,破解密码的难度比纯MD5高了好几倍。

3.加盐在java中实现

下面java代码中对密码加密1024次,盐值为user_id,每个用户都通过自己的user_id生成私有的salt。
最终获取到的是用户输入密码通过哈希算法,哈希盐值生成的哈希密码信息。

加盐部分代码

 /*
        * MD5加密:
        * 使用SimpleHash类对原始密码进行加密。
        * 第一个参数代表使用MD5方式加密
        * 第二个参数为原始密码
        * 第三个参数为盐值,即userid
        * 第四个参数为加密次数
        * 最后用toHex()方法将加密后的密码转成String
        * */


 ByteSource salt = ByteSource.Util.bytes(user_id);
 String newPs = new SimpleHash("MD5", password, salt, 1024).toHex();
复制代码

4.主要的class源码

ByteSource接口

ByteSource类作用是返回md5加密方法中所需要的salt的统一二进制类型。

    byte[] getBytes();
 
    String toHex();
 
    String toBase64();
 
    boolean isEmpty();

SimpleHash类

SimpleHash类继承于hash类。hash类下有几个不同的子类。

 常见的为Md5Hash,里面有两个主要的方法:分别用于不同的编码类型的加密Hex和Base64.

      public static Md5Hash fromHexString(String hex) {
        Md5Hash hash = new Md5Hash();
        hash.setBytes(Hex.decode(hex));
        return hash;
    }
 
    public static Md5Hash fromBase64String(String base64) {
        Md5Hash hash = new Md5Hash();
        hash.setBytes(Base64.decode(base64));
        return hash;
    }
复制代码

setBytes为:把原来的hex或者base64的编码方式变成MD5Hash类型的编码。

 public void setBytes(byte[] alreadyHashedBytes) {
        this.bytes = alreadyHashedBytes;
        this.hexEncoded = null;
        this.base64Encoded = null;
    }
复制代码

SimpleHash类中:hashIterations为加密的次数,如果hashIterations>1,则加密次数为hashIterations,否则为1.如果盐值不为空,就加进去。

如何使用加盐值
1.首先得到明文的hash值
2.计算获取MD5明文hash值
3.加入生成的盐
4.MD5插入加盐值得到hash
5.得到最终的密文

 /*
        * MD5加密:
        * 使用SimpleHash类对原始密码进行加密。
        * 第一个参数代表使用MD5方式加密
        * 第二个参数为原始密码
        * 第三个参数为盐值,即userid
        * 第四个参数为加密次数
        * 最后用toHex()方法将加密后的密码转成String
        * */
public SimpleHash(String algorithmName, Object source, Object salt, int hashIterations) throws CodecException, UnknownAlgorithmException {
        this.hexEncoded = null;
        this.base64Encoded = null;
        if(!StringUtils.hasText(algorithmName)) {
            throw new NullPointerException("algorithmName argument cannot be null or empty.");
        } else {
            this.algorithmName = algorithmName;
            this.iterations = Math.max(1, hashIterations);
            ByteSource saltBytes = null;
            if(salt != null) {
                saltBytes = this.convertSaltToBytes(salt);
                this.salt = saltBytes;
            }
 
            ByteSource sourceBytes = this.convertSourceToBytes(source);
            this.hash(sourceBytes, saltBytes, hashIterations);
        }
    }
复制代码

  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值