Package com.github.ebnew.ki4so.core.authentication

Source Code of com.github.ebnew.ki4so.core.authentication.EncryCredentialManagerImpl

package com.github.ebnew.ki4so.core.authentication;

import java.net.URLDecoder;
import java.net.URLEncoder;
import java.security.Key;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.alibaba.fastjson.JSON;
import com.github.ebnew.ki4so.common.Base64Coder;
import com.github.ebnew.ki4so.common.DESCoder;
import com.github.ebnew.ki4so.common.utils.StringUtils;
import com.github.ebnew.ki4so.core.exception.InvalidEncryCredentialException;
import com.github.ebnew.ki4so.core.key.KeyService;
import com.github.ebnew.ki4so.core.key.Ki4soKey;
import com.github.ebnew.ki4so.core.model.EncryCredentialInfo;

public class EncryCredentialManagerImpl implements EncryCredentialManager{
 
  private KeyService keyService;
 
  public void setKeyService(KeyService keyService) {
    this.keyService = keyService;
  }

  private static final Logger LOGGER = Logger.getLogger(EncryCredentialManagerImpl.class.getName());

  @Override
  public EncryCredentialInfo decrypt(EncryCredential encryCredential) {
    //不为空。
    if(encryCredential!=null && !StringUtils.isEmpty(encryCredential.getCredential())){
      String credential = encryCredential.getCredential();
      return parseEncryCredential(credential);
    }
    //若为空信息,则返回空。
    return null;
  }
 
  /**
   * 解析加密后的凭据信息为凭据对象。过程与加密过程相反的逆过程。
   * @param 加密过的凭据字符串。
   * @return 凭据对象。
   * @throws Exception
   */
  private EncryCredentialInfo parseEncryCredential(String credential) throws InvalidEncryCredentialException{
    EncryCredentialInfo encryCredentialInfo = new EncryCredentialInfo();
    try{
      //先使用URL解码,再用BASE64进行解码。
      credential = URLDecoder.decode(credential, "UTF-8");
      credential = new String(Base64Coder.decryptBASE64(credential));
     
      //问号分割字符串。
      String[] items = credential.split("\\?");
      //如果长度是2.
      if(items.length==2){
        //第2个字符串不为空,先解析第二个字符串。
        if(items[1]!=null && items[1].length()>0){
          //使用&分割字符。
          String[] params = items[1].split("&");
          for(int i=0; i<params.length; i++){
            if(params[i]!=null){
              //使用等号分割。
              String[] values = params[i].split("=");
              if(values!=null && values.length==2){
                if("appId".equals(values[0])){
                  encryCredentialInfo.setAppId(values[1]);
                }
                else if("keyId".equals(values[0])){
                  encryCredentialInfo.setKeyId(values[1]);
                }
              }
            }
          }
        }
        else{
          throw new InvalidEncryCredentialException();
        }
        //第1个字符串不为空
        if(!StringUtils.isEmpty(items[0])){
          //使用base64解码为源字符串。
          byte[] data =  Base64Coder.decryptBASE64(items[0]);
          //查询键值。
          Ki4soKey ki4soKey = keyService.findKeyByKeyId(encryCredentialInfo.getKeyId());
          if(ki4soKey!=null){
            //使用密钥进行解密。
            byte[] origin = DESCoder.decrypt(data, ki4soKey.toSecurityKey());
            //将byte数组转换为字符串。
            String json = new String(origin);
            @SuppressWarnings("rawtypes")
            Map map = (Map)JSON.parse(json);
            if(map!=null){
              Object userId = map.get("userId");
              Object createTime = map.get("createTime");
              Object expiredTime = map.get("expiredTime");
              encryCredentialInfo.setUserId(userId==null?null:userId.toString());
              encryCredentialInfo.setCreateTime(createTime==null?null:new Date((Long.parseLong(createTime.toString()))));
              encryCredentialInfo.setExpiredTime(expiredTime==null?null:new Date((Long.parseLong(expiredTime.toString()))));
            }
          }
        }
        else{
          throw new InvalidEncryCredentialException();
        }
      }
      else{
        throw new InvalidEncryCredentialException();
      }
    }
    catch (Exception e) {
      LOGGER.log(Level.SEVERE, "parse encry credential exception", e);
      throw new InvalidEncryCredentialException();
    }
   
    return encryCredentialInfo;
  }

  /**
   * 编码的实现流程如下:
   * 1.将加密凭据信息的敏感字段包括:userId,createTime和expiredTime字段
   * 组合成json格式的数据,然后使用密钥对该字符串进行DES加密,再将加密后的字符串通过Base64编码。
   * 2.将上述加密串与其它非敏感信息进行拼接,格式如是:[敏感信息加密串]?appId=1&keyId=2
   * 其中敏感信息加密串为第一步得到的结果,appId为应用标识,keyId为密钥标识。
   * 3.使用URL进行编码。防止tomcat7下报cookie错误。
   */
  @Override
  public String encrypt(EncryCredentialInfo encryCredentialInfo) {
    StringBuffer sb = new StringBuffer();
    if(encryCredentialInfo!=null){
      try {
        String data = encryptSensitiveInfo(encryCredentialInfo);
        sb.append(data).append("?appId=").append(encryCredentialInfo.getAppId())
        .append("&keyId=").append(encryCredentialInfo.getKeyId());
        //再进行BASE64编码,避免传输错误。
        return URLEncoder.encode(Base64Coder.encryptBASE64(sb.toString().getBytes()), "UTF-8");
      } catch (Exception e) {
        LOGGER.log(Level.SEVERE, "encrypt data exception", e);
      }
    }
    return sb.toString();
  }
 
  private String encryptSensitiveInfo(EncryCredentialInfo encryCredentialInfo) throws Exception{
    Map<String, Object> map = new HashMap<String, Object>();
    map.put("userId", encryCredentialInfo.getUserId());
    if(encryCredentialInfo.getCreateTime()!=null){
      map.put("createTime", encryCredentialInfo.getCreateTime().getTime());
    }
    if(encryCredentialInfo.getExpiredTime()!=null){
      map.put("expiredTime", encryCredentialInfo.getExpiredTime().getTime());
    }
    //查询键值。
    Ki4soKey ki4soKey = keyService.findKeyByKeyId(encryCredentialInfo.getKeyId());
    if(ki4soKey!=null){
      //查询键值。
      Key key = ki4soKey.toSecurityKey();
      if(key!=null){
        byte[] data = DESCoder.encrypt(JSON.toJSONBytes(map), key);
        //先用BASE64编码,再用URL编码。
        return Base64Coder.encryptBASE64(data);
      }
      return "";
    }
    return "";
  }

  @Override
  public boolean checkEncryCredentialInfo(
      EncryCredentialInfo encryCredentialInfo) {
    if(encryCredentialInfo!=null){
      //无凭据对应的用户标识,则无效。
      if(StringUtils.isEmpty(encryCredentialInfo.getUserId())){
        return false;
      }
      Date now = getCurrentDate();
      if(encryCredentialInfo.getExpiredTime()!=null){
        //将未来过期时间减去当前时间。
        long deta = encryCredentialInfo.getExpiredTime().getTime() - now.getTime();
        //若差值大于0,表示过期时间还没有到,凭据继续可以有效使用。
        if(deta>0){
          return true;
        }
      }
    }
    return false;
  }
 
  /**
   * 获得当前时间。
   * @return
   */
  private Date getCurrentDate(){
    return new Date();
  }
}
TOP

Related Classes of com.github.ebnew.ki4so.core.authentication.EncryCredentialManagerImpl

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.