// base64编码/解码操作
String str = "hello";
String base64Encoded = Base64.encodeToString(str.getBytes());
String str2 = Base64.decodeToString(base64Encoded);
Assert.assertEquals(str, str2);
// 16进制字符串编码/解码
String str = "hello";
String base64Encoded = Hex.encodeToString(str.getBytes());
String str2 = new String(Hex.decode(base64Encoded.getBytes()));
Assert.assertEquals(str, str2);
//MD5加密
String str = "hello";
String salt = "123";
String md5 = new Md5Hash(str, salt).toString();//还可以转换为 toBase64()/toHex()
如上代码通过盐“123”MD5散列“hello”。另外散列时还可以指定散列次数,如2次表示:md5(md5(str)):“new Md5Hash(str, salt, 2).toString()”。
// 使用SHA256算法生成相应的散列数据,另外还有如SHA1、SHA512算法。
String str = "hello";
String salt = "123";
String sha1 = new Sha256Hash(str, salt).toString();
Shiro还提供了通用的散列支持:
String str = "hello";
String salt = "123";
//通过调用SimpleHash时指定散列算法,其内部使用了Java的MessageDigest实现。
String simpleHash = new SimpleHash("SHA-1", str, salt).toString();
为了方便使用,Shiro提供了HashService,默认提供了DefaultHashService实现。
DefaultHashService hashService = new DefaultHashService(); //默认算法SHA-512
hashService.setHashAlgorithmName("SHA-512");
hashService.setPrivateSalt(new SimpleByteSource("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();
String hex = hashService.computeHash(request).toHex();
1、首先创建一个DefaultHashService,默认使用SHA-512算法;
SecureRandomNumberGenerator用于生成一个随机数:
SecureRandomNumberGenerator randomNumberGenerator =
new SecureRandomNumberGenerator();
randomNumberGenerator.setSeed("123".getBytes());
String hex = randomNumberGenerator.nextBytes().toHex();
// AES算法实现:
AesCipherService aesCipherService = new AesCipherService();
aesCipherService.setKeySize(128); //设置key长度
//生成key
Key key = aesCipherService.generateNewKey();
String text = "hello";
//加密
String encrptText =
aesCipherService.encrypt(text.getBytes(), key.getEncoded()).toHex();
//解密
String text2 =
new String(aesCipherService.decrypt(Hex.decode(encrptText), key.getEncoded()).getBytes());
Assert.assertEquals(text, text2);
public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {
String username = (String)token.getPrincipal();
//retry count + 1
Element element = passwordRetryCache.get(username);
if(element == null) {
element = new Element(username , new AtomicInteger(0));
passwordRetryCache.put(element);
}
AtomicInteger retryCount = (AtomicInteger)element.getObjectValue();
if(retryCount.incrementAndGet() > 5) {
//if retry count > 5 throw
throw new ExcessiveAttemptsException();
}
boolean matches = super.doCredentialsMatch(token, info);
if(matches) {
//clear retry count
passwordRetryCache.remove(username);
}
return matches;
}
如上代码逻辑比较简单,即如果密码输入正确清除cache中的记录;否则cache中的重试次数+1,如果超出5次那么抛出异常表示超出重试次数了。