你的位置:首页 > 软件开发 > ASP.net > 第五章 编码/加密——《跟我学Shiro》

第五章 编码/加密——《跟我学Shiro》

发布时间:2015-09-03 03:00:11
在涉及到密码存储问题上,应该加密/生成密码摘要存储,而不是存储明文密码。比如之前的600w csdn账号泄露对用户可能造成很大损失,因此应加密/生成不可逆的摘要方式存储。 5.1 编码/解码 Shiro提供了base64和16进制字符串编码/解码的API支持,方便一些编码 ...

在涉及到密码存储问题上,应该加密/生成密码摘要存储,而不是存储明文密码。比如之前的600w csdn账号泄露对用户可能造成很大损失,因此应加密/生成不可逆的摘要方式存储。

 

5.1 编码/解码 

Shiro提供了base64和16进制字符串编码/解码的API支持,方便一些编码解码操作。Shiro内部的一些数据的存储/表示都使用了base64和16进制字符串。

Java代码  
  1. String str = "hello";  
  2. String base64Encoded = Base64.encodeToString(str.getBytes());  
  3. String str2 = Base64.decodeToString(base64Encoded);  
  4. Assert.assertEquals(str, str2);   
  1. String str = "hello";  
  2. String base64Encoded = Hex.encodeToString(str.getBytes());  
  3. String str2 = new String(Hex.decode(base64Encoded.getBytes()));  
  4. Assert.assertEquals(str, str2);   
  1. String str = "hello";  
  2. String salt = "123";  
  3. String md5 = new Md5Hash(str, salt).toString();//还可以转换为 toBase64()/toHex()   
  1. String str = "hello";  
  2. String salt = "123";  
  3. String sha1 = new Sha256Hash(str, salt).toString();   
  1. String str = "hello";  
  2. String salt = "123";  
  3. //内部使用MessageDigest  
  4. String simpleHash = new SimpleHash("SHA-1", str, salt).toString();   
  1. DefaultHashService hashService = new DefaultHashService(); //默认算法SHA-512  
  2. hashService.setHashAlgorithmName("SHA-512");  
  3. hashService.setPrivateSalt(new SimpleByteSource("123")); //私盐,默认无  
  4. hashService.setGeneratePublicSalt(true);//是否生成公盐,默认false  
  5. hashService.setRandomNumberGenerator(new SecureRandomNumberGenerator());//用于生成公盐。默认就这个  
  6. hashService.setHashIterations(1); //生成Hash值的迭代次数  
  7.   
  8. HashRequest request = new HashRequest.Builder()  
  9.             .setAlgorithmName("MD5").setSource(ByteSource.Util.bytes("hello"))  
  10.             .setSalt(ByteSource.Util.bytes("123")).setIterations(2).build();  
  11. String hex = hashService.computeHash(request).toHex();   
  1. SecureRandomNumberGenerator randomNumberGenerator =  
  2.      new SecureRandomNumberGenerator();  
  3. randomNumberGenerator.setSeed("123".getBytes());  
  4. String hex = randomNumberGenerator.nextBytes().toHex();   
  1. AesCipherService aesCipherService = new AesCipherService();  
  2. aesCipherService.setKeySize(128); //设置key长度  
  3. //生成key  
  4. Key key = aesCipherService.generateNewKey();  
  5. String text = "hello";  
  6. //加密  
  7. String encrptText =   
  8. aesCipherService.encrypt(text.getBytes(), key.getEncoded()).toHex();  
  9. //解密  
  10. String text2 =  
  11.  new String(aesCipherService.decrypt(Hex.decode(encrptText), key.getEncoded()).getBytes());  
  12.   
  13. Assert.assertEquals(text, text2);   
  1. public interface PasswordService {  
  2.     //输入明文密码得到密文密码  
  3.     String encryptPassword(Object plaintextPassword) throws IllegalArgumentException;  
  4. }  
  1. public interface CredentialsMatcher {  
  2.     //匹配用户输入的token的凭证(未加密)与系统提供的凭证(已加密)  
  3.     boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info);  
  4. }   
  1. public class MyRealm extends AuthorizingRealm {  
  2.     private PasswordService passwordService;  
  3.     public void setPasswordService(PasswordService passwordService) {  
  4.         this.passwordService = passwordService;  
  5.     }  
  6.      //省略doGetAuthorizationInfo,具体看代码   
  7.     @Override  
  8.     protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {  
  9.         return new SimpleAuthenticationInfo(  
  10.                 "wu",  
  11.                 passwordService.encryptPassword("123"),  
  12.                 getName());  
  13.     }  
  14. }   
  1. [main]  
  2. passwordService=org.apache.shiro.authc.credential.DefaultPasswordService  
  3. hashService=org.apache.shiro.crypto.hash.DefaultHashService  
  4. passwordService.hashService=$hashService  
  5. hashFormat=org.apache.shiro.crypto.hash.format.Shiro1CryptFormat  
  6. passwordService.hashFormat=$hashFormat  
  7. hashFormatFactory=org.apache.shiro.crypto.hash.format.DefaultHashFormatFactory  
  8. passwordService.hashFormatFactory=$hashFormatFactory  
  9.   
  10. passwordMatcher=org.apache.shiro.authc.credential.PasswordMatcher  
  11. passwordMatcher.passwordService=$passwordService  
  12.   
  13. myRealm=com.github.zhangkaitao.shiro.chapter5.hash.realm.MyRealm  
  14. myRealm.passwordService=$passwordService  
  15. myRealm.credentialsMatcher=$passwordMatcher  
  16. securityManager.realms=$myRealm   
  1. String algorithmName = "md5";  
  2. String username = "liu";  
  3. String password = "123";  
  4. String salt1 = username;  
  5. String salt2 = new SecureRandomNumberGenerator().nextBytes().toHex();  
  6. int hashIterations = 2;  
  7.   
  8. SimpleHash hash = new SimpleHash(algorithmName, password, salt1 + salt2, hashIterations);  
  9. String encodedPassword = hash.toHex();   
  1. protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {  
  2.     String username = "liu"; //用户名及salt1  
  3.     String password = "202cb962ac59075b964b07152d234b70"; //加密后的密码  
  4.     String salt2 = "202cb962ac59075b964b07152d234b70";  
  5. SimpleAuthenticationInfo ai =   
  6.         new SimpleAuthenticationInfo(username, password, getName());  
  7.     ai.setCredentialsSalt(ByteSource.Util.bytes(username+salt2)); //盐是用户名+随机数  
  8.         return ai;  
  9. }   
  1. jdbcRealm.saltStyle=COLUMN  
  2. jdbcRealm.authenticationQuery=select password, concat(username,password_salt) from users where username = ?  
  3. jdbcRealm.credentialsMatcher=$credentialsMatcher   
  1. [main]  
  2. credentialsMatcher=org.apache.shiro.authc.credential.HashedCredentialsMatcher  
  3. credentialsMatcher.hashAlgorithmName=md5  
  4. credentialsMatcher.hashIterations=2  
  5. credentialsMatcher.storedCredentialsHexEncoded=true  
  6. myRealm=com.github.zhangkaitao.shiro.chapter5.hash.realm.MyRealm2  
  7. myRealm.credentialsMatcher=$credentialsMatcher  
  8. securityManager.realms=$myRealm   
  1. public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {  
  2.        String username = (String)token.getPrincipal();  
  3.         //retry count + 1  
  4.         Element element = passwordRetryCache.get(username);  
  5.         if(element == null) {  
  6.             element = new Element(username , new AtomicInteger(0));  
  7.             passwordRetryCache.put(element);  
  8.         }  
  9.         AtomicInteger retryCount = (AtomicInteger)element.getObjectValue();  
  10.         if(retryCount.incrementAndGet() > 5) {  
  11.             //if retry count > 5 throw  
  12.             throw new ExcessiveAttemptsException();  
  13.         }  
  14.   
  15.         boolean matches = super.doCredentialsMatch(token, info);  
  16.         if(matches) {  
  17.             //clear retry count  
  18.             passwordRetryCache.remove(username);  
  19.         }  
  20.         return matches;  
  21. }   

原标题:第五章 编码/加密——《跟我学Shiro》

关键词:Shiro

*特别声明:以上内容来自于网络收集,著作权属原作者所有,如有侵权,请联系我们: admin#shaoqun.com (#换成@)。

可能感兴趣文章

我的浏览记录