• 文章标题


    1,加密工具类的熟悉

    下面是一个工具类来探测和熟悉这些工具类的使用:

    package com.util; 
    import com.domain.User; 
    import com.google.common.base.Preconditions; 
    import com.google.common.base.Strings; 
    import com.sun.crypto.provider.AESKeyGenerator; 
    import org.apache.shiro.codec.Base64; 
    import org.apache.shiro.codec.CodecSupport; 
    import org.apache.shiro.codec.H64; 
    import org.apache.shiro.codec.Hex; 
    import org.apache.shiro.crypto.AesCipherService; 
    import org.apache.shiro.crypto.SecureRandomNumberGenerator; 
    import org.apache.shiro.crypto.hash.Md5Hash; 
    import java.security.Key; 
    /** 
    * User: cutter.li 
    * Date: 2014/6/27 0027 
    * Time: 16:49 
    * 备注: shiro进行加密解密的工具类封装 
    */ 
    public final class EndecryptUtils { 
        /** 
         * base64进制加密 
         * 
         * @param password 
         * @return 
         */ 
        public static String encrytBase64(String password) { 
            Preconditions.checkArgument(!Strings.isNullOrEmpty(password), "不能为空"); 
            byte[] bytes = password.getBytes(); 
            return Base64.encodeToString(bytes); 
        } 
        /** 
         * base64进制解密 
         * @param cipherText 
         * @return 
         */ 
        public static String decryptBase64(String cipherText) { 
            Preconditions.checkArgument(!Strings.isNullOrEmpty(cipherText), "消息摘要不能为空"); 
            return Base64.decodeToString(cipherText); 
        } 
        /** 
         * 16进制加密 
         * 
         * @param password 
         * @return 
         */ 
        public static String encrytHex(String password) { 
            Preconditions.checkArgument(!Strings.isNullOrEmpty(password), "不能为空"); 
            byte[] bytes = password.getBytes(); 
            return Hex.encodeToString(bytes); 
        } 
        /** 
         * 16进制解密 
         * @param cipherText 
         * @return 
         */ 
        public static String decryptHex(String cipherText) { 
            Preconditions.checkArgument(!Strings.isNullOrEmpty(cipherText), "消息摘要不能为空"); 
            return new String(Hex.decode(cipherText)); 
        } 
        public static String generateKey() 
        { 
            AesCipherService aesCipherService=new AesCipherService(); 
            Key key=aesCipherService.generateNewKey(); 
            return Base64.encodeToString(key.getEncoded()); 
        } 
        /** 
         * 对密码进行md5加密,并返回密文和salt,包含在User对象中 
         * @param username 用户名 
         * @param password 密码 
         * @return 密文和salt 
         */ 
        public static User md5Password(String username,String password){ 
            Preconditions.checkArgument(!Strings.isNullOrEmpty(username),"username不能为空"); 
            Preconditions.checkArgument(!Strings.isNullOrEmpty(password),"password不能为空"); 
            SecureRandomNumberGenerator secureRandomNumberGenerator=new SecureRandomNumberGenerator(); 
            String salt= secureRandomNumberGenerator.nextBytes().toHex(); 
            //组合username,两次迭代,对密码进行加密 
            String password_cipherText= new Md5Hash(password,username+salt,2).toBase64(); 
            User user=new User(); 
            user.setPassword(password_cipherText); 
            user.setSalt(salt); 
            user.setUsername(username); 
            return user; 
        } 
        public static void main(String[] args) { 
            String password = "admin"; 
            String cipherText = encrytHex(password); 
            System.out.println(password + "hex加密之后的密文是:" + cipherText); 
            String decrptPassword=decryptHex(cipherText); 
            System.out.println(cipherText + "hex解密之后的密码是:" + decrptPassword); 
            String cipherText_base64 = encrytBase64(password); 
            System.out.println(password + "base64加密之后的密文是:" + cipherText_base64); 
            String decrptPassword_base64=decryptBase64(cipherText_base64); 
            System.out.println(cipherText_base64 + "base64解密之后的密码是:" + decrptPassword_base64); 
            String h64=  H64.encodeToString(password.getBytes()); 
            System.out.println(h64); 
            String salt="7road"; 
            String cipherText_md5= new Md5Hash(password,salt,4).toHex(); 
            System.out.println(password+"通过md5加密之后的密文是:"+cipherText_md5); 
            System.out.println(generateKey()); 
            System.out.println("=========================================================="); 
            AesCipherService aesCipherService=new AesCipherService(); 
            aesCipherService.setKeySize(128); 
            Key key=aesCipherService.generateNewKey(); 
            String aes_cipherText= aesCipherService.encrypt(password.getBytes(),key.getEncoded()).toHex(); 
            System.out.println(password+" aes加密的密文是:"+aes_cipherText); 
            String aes_mingwen=new String(aesCipherService.decrypt(Hex.decode(aes_cipherText),key.getEncoded()).getBytes()); 
            System.out.println(aes_cipherText+" aes解密的明文是:"+aes_mingwen); 
        } 
    }

    2,一个综合点的例子,配置帐号的密码生成方式,并利用ehcache,设定输错密码多少次,用户被锁定一个小时;

    1,提供一个ehcache的简单实用类

    package com.util.cache; 
    import net.sf.ehcache.Cache; 
    import net.sf.ehcache.CacheManager; 
    import net.sf.ehcache.Element; 
    import net.sf.ehcache.config.CacheConfiguration; 
    import net.sf.ehcache.store.MemoryStoreEvictionPolicy; 
    /** 
    * User: cutter.li 
    * Date: 2014/6/30 0030 
    * Time: 15:32 
    * 备注: ehcache的缓存工具类 
    */ 
    public final class EhcacheUtil { 
        private static final CacheManager cacheManager = CacheManager.getInstance(); 
        /** 
         * 创建ehcache缓存,创建之后的有效期是1小时 
         */ 
       private static Cache cache = new Cache(new CacheConfiguration("systemCache", 5000).memoryStoreEvictionPolicy(MemoryStoreEvictionPolicy.FIFO).timeoutMillis(300).timeToLiveSeconds( 60 * 60)); 
        static { 
            cacheManager.addCache(cache); 
        } 
        public static void putItem(String key, Object item) { 
            if (cache.get(key) != null) { 
                cache.remove(key); 
            } 
            Element element = new Element(key, item); 
            cache.put(element); 
        } 
        public static void removeItem(String key) { 
            cache.remove(key); 
        } 
        public static void updateItem(String key, Object value) { 
            putItem(key, value); 
        } 
        public static Object getItem(String key) { 
            Element element=  cache.get(key); 
            if(null!=element) 
            { 
                return element.getObjectValue(); 
            } 
            return null; 
        } 
    }
    
    
    2,提供加密和校验密文的方法
    
    
    
    /** 
         * 对密码进行md5加密,并返回密文和salt,包含在User对象中 
         * @param username 用户名 
         * @param password 密码 
         * @return 密文和salt 
         */ 
        public static User md5Password(String username,String password){ 
            Preconditions.checkArgument(!Strings.isNullOrEmpty(username),"username不能为空"); 
            Preconditions.checkArgument(!Strings.isNullOrEmpty(password),"password不能为空"); 
            SecureRandomNumberGenerator secureRandomNumberGenerator=new SecureRandomNumberGenerator(); 
            String salt= secureRandomNumberGenerator.nextBytes().toHex(); 
            //组合username,两次迭代,对密码进行加密 
            String password_cipherText= new Md5Hash(password,username+salt,2).toHex(); 
            User user=new User(); 
            user.setPassword(password_cipherText); 
            user.setSalt(salt); 
            user.setUsername(username); 
            return user; 
        } 
        /** 
         * 通过username,password,salt,校验密文是否匹配 ,校验规则其实在配置文件中,这里为了清晰,写下来 
         * @param username 用户名 
         * @param password 原密码 
         * @param salt  盐 
         * @param md5cipherText 密文 
         * @return 
         */ 
        public static  boolean checkMd5Password(String username,String password,String salt,String md5cipherText) 
        { 
            Preconditions.checkArgument(!Strings.isNullOrEmpty(username),"username不能为空"); 
            Preconditions.checkArgument(!Strings.isNullOrEmpty(password),"password不能为空"); 
            Preconditions.checkArgument(!Strings.isNullOrEmpty(md5cipherText),"md5cipherText不能为空"); 
            //组合username,两次迭代,对密码进行加密 
            String password_cipherText= new Md5Hash(password,username+salt,2).toHex(); 
            return md5cipherText.equals(password_cipherText); 
        }

    3,配置认证的数据源使用的密码校验接口

      <bean id="myRealm" class="com.util.MysqlJdbcRealM"> 
            <property name="credentialsMatcher" ref="passwordMatcher"></property> 
        </bean> 
        <bean id="passwordMatcher" class="com.util.LimitRetryHashedMatcher"> 
       <property name="hashAlgorithmName" value="md5"></property> 
            <property name="hashIterations" value="2"></property> 
            <property name="storedCredentialsHexEncoded" value="true"></property> 
        </bean>

    4,注册和登录方法的修改

    /
    * 用户注册
    *
    * @param entity
    * @return
    */
    @Override
    public ResponseEntity createSubmit(User entity) {
    //加密用户输入的密码,得到密码的摘要和盐,保存到数据库
    User user = EndecryptUtils.md5Password(entity.getUsername(), entity.getPassword());
    entity.setPassword(user.getPassword());
    entity.setSalt(user.getSalt());
    Map

    package com.util; 
    import com.util.cache.EhcacheUtil; 
    import org.apache.shiro.authc.AuthenticationInfo; 
    import org.apache.shiro.authc.AuthenticationToken; 
    import org.apache.shiro.authc.ExcessiveAttemptsException; 
    import org.apache.shiro.authc.credential.HashedCredentialsMatcher; 
    import java.util.concurrent.atomic.AtomicInteger; 
    /** 
    * User: cutter.li 
    * Date: 2014/6/30 0030 
    * Time: 15:22 
    * 备注: 限制登录次数,如果5次出错,锁定1个小时 
    */ 
    public class LimitRetryHashedMatcher extends HashedCredentialsMatcher { 
        @Override 
        public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) { 
            String username = (String) token.getPrincipal(); 
    //retrycount + 1 
            Object element = EhcacheUtil.getItem(username); 
            if (element == null) { 
                EhcacheUtil.putItem(username, 1); 
                element=0; 
            }else{ 
                int count=Integer.parseInt(element.toString())+1; 
                element=count; 
                EhcacheUtil.putItem(username,element); 
            } 
            AtomicInteger retryCount = new AtomicInteger(Integer.parseInt(element.toString())); 
            if (retryCount.incrementAndGet() > 5) { 
    //if retrycount >5 throw 
                throw new ExcessiveAttemptsException(); 
            } 
            boolean matches = super.doCredentialsMatch(token, info); 
            if (matches) { 
    //clear retrycount 
                EhcacheUtil.removeItem(username); 
            } 
            return matches; 
        } 
    }
  • 相关阅读:
    编程实现Windows系统自动登录
    IOS开发笔记
    所有的GUI Toolkit,类型之多真开眼界
    文件保护DEP
    Delphi 重启应用程序(创建Bat文件的Process)
    Linux的几个概念,常用命令学习
    Delphi内存操作API函数(备查,并一一学习)
    Servle中的会话管理
    Windows软件在Linux上的等价/替代/模仿软件列表 (抄一个)
    Go 的文件系统抽象 Afero
  • 原文地址:https://www.cnblogs.com/lllini/p/11955277.html
Copyright © 2020-2023  润新知