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);
}
}
复制代码