散列算法一般用于生成数据的摘要信息,是一种不可逆的算法,一般适合存储密码之类的数据,常见的散列算法如 MD5、SHA等。一般进行散列时最好提供一个 salt(盐),比如加密密码“admin”,产生的散列值是“21232f297a57a5a743894a0e4a801fc3”,可以到一些 md5解密网站很容易的通过散列值得到密码“admin”,即如果直接对密码进行散列相对来说破解更容易,此时我们可以加一些只有系统知道的干扰数据,如用户名和 ID(即盐);这样散列的对象是“密码+用户名+ID”,这样生成的散列值相对来说更难破解。
public PasswordHash(Object source, String salt) { this.algorithmName = "md5"; // 加密算法 this.hashIterations = 996; // 散列次数 this.salt = salt; // 盐值 this.source = source; // 加密数据 this.hexEncoded = new SimpleHash(algorithmName, source, salt, hashIterations).toHex(); }
通过调用 SimpleHash 时指定散列算法,其内部使用了 Java的 MessageDigest 实现。为了方便使用,Shiro提供了HashService,默认提供了 DefaultHashService实现:
DefaultHashService hashService = new DefaultHashService(); /* 默认算法 SHA-512 */ hashService.setHashAlgorithmName( "SHA-512" ); hashService.setPrivateSalt( newSimpleByteSource( "123" ) ); /* 私盐,默认无 */ hashService.setGeneratePublicSalt( true ); /* 是否生成公盐,默认false */ hashService.setRandomNumberGenerator( new SecureRandomNumberGenerator() ); /* 用于生成公盐。默认就这个 */ hashService.setHashIterations( 1 ); /* 生成 Hash 值的迭代次数 */ HashRequest request = new HashRequest.Builder() .setAlgorithmName( "MD5" ).setSource( ByteSource.Util.bytes( "hello" ) ) .setSalt( ByteSource.Util.bytes( "123" ) ).setIterations( 2 ).build(); Stringhex = hashService.computeHash( request ).toHex();
1、首先创建一个DefaultHashService,默认使用SHA-512算法;
2、可以通过hashAlgorithmName属性修改算法;
3、可以通过privateSalt设置一个私盐,其在散列时自动与用户传入的公盐混合产生一个新盐;
4、可以通过generatePublicSalt属性在用户没有传入公盐的情况下是否生成公盐;
5、可以设置randomNumberGenerator用于生成公盐;
6、可以设置hashIterations属性来修改默认加密迭代次数;
7、需要构建一个HashRequest,传入算法、数据、公盐、迭代次数。