API接口安全——加密

package com.lili.api.util;

import java.io.IOException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.security.GeneralSecurityException;
import java.security.MessageDigest;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.zhph.api.vo.ApiModel;

/**
 * 外部接口工具类
 *
 */
public class SignUtils {
private static Logger LOGGER = LoggerFactory.getLogger(SignUtils.class);
    
    private static final String secretKey = "2116b98d7dc71ec2cd3a9f50";
    private static final String appKeyId= "375028bd0e680e91be502e86";
    
     public static void main(String[] args)  
        {  
            //参数签名算法测试例子  
            HashMap<String, String> signMap = new HashMap<String, String>();  
            signMap.put("appkey",appKeyId);  
            signMap.put("random_str","haxf");  
            String dateStr = (new Date()).getTime()+"";
            signMap.put("timestamp",dateStr);  
            System.out.println("得到签名sign1:"+getSign(signMap,secretKey));
            StringBuffer sb = new StringBuffer("http://localhost:8080/dome/api/v2/getUser?appkey="+appKeyId);
            sb.append("&timestamp=").append(dateStr).append("&random_str=vdedg").append("&sign=").append(getSign(signMap,secretKey));
            System.out.println(sb.toString());
        }  
     
     
     /**
      * 外部接口签名验证
      * @param request
      * @return
      */
     public static boolean checkSign(HttpServletRequest request,HttpServletResponse response){
         ApiModel apiModel = new ApiModel();
         String appid = request.getParameter("appkey");//appid
         String sign = request.getParameter("sign");//签名
         String random_str = request.getParameter("random_str");//签名
         String timestamp = request.getParameter("timestamp");//时间戳
         if(appid==null ||sign==null||timestamp==null||random_str==null) {
             apiModel.info(401,"鉴权失败,缺少鉴权参数,请检查!");
             print(response, apiModel);
             return false;
         }
         
         if(!appid.equals(appKeyId)){
             apiModel.info(401,"appId 不正确!");
             print(response, apiModel);
             return  false;
         }
        //check时间戳的值是否在当前时间戳前后一小时以内
        String currTimestamp = String.valueOf(new Date().getTime() / 1000); // 当前时间的时间戳
        int currTimestampNum = Integer.parseInt(currTimestamp);
        long verifyTimestampNum = Long.valueOf(timestamp)/1000; // 时间戳的数值
        // 在5分钟范围之外,访问已过期
        if (Math.abs(verifyTimestampNum - currTimestampNum) > 300) {
            apiModel.info(401,"sigin已经过期");
            print(response, apiModel);
            return false;
        }
        //检查sigin是否过期
         //Enumeration<?> pNames =  request.getParameterNames();  
         Map<String, String> params = new HashMap<String, String>();  
//         while (pNames.hasMoreElements()) {  
//             String pName = (String) pNames.nextElement();  
//             if("sign".equals(pName)) continue;  
//             String pValue = (String)request.getParameter(pName);  
//             params.put(pName, pValue);  
//         }
         params.put("appkey", appid);
         params.put("random_str", random_str);
         params.put("timestamp", timestamp);
         if(!sign.equals(getSign(params, secretKey))){
             apiModel.info(401,"sigin不正确。");
             print(response, apiModel);
             return false;
         }
         return true;
     }
     
      
    public static String utf8Encoding(String value, String sourceCharsetName) {  
        try {  
            return new String(value.getBytes(sourceCharsetName), "UTF-8");  
        } catch (UnsupportedEncodingException e) {  
            throw new IllegalArgumentException(e);  
        }  
    }  
  
  
  
    private static byte[] getMD5Digest(String data) throws IOException {  
        byte[] bytes = null;  
        try {  
            MessageDigest md = MessageDigest.getInstance("MD5");  
            bytes = md.digest(data.getBytes("UTF-8"));  
        } catch (GeneralSecurityException gse) {  
            throw new IOException(gse);  
        }  
        return bytes;  
    }  
  
  
    private static String byte2hex(byte[] bytes) {  
        StringBuilder sign = new StringBuilder();  
        for (int i = 0; i < bytes.length; i++) {  
            String hex = Integer.toHexString(bytes[i] & 0xFF);  
            if (hex.length() == 1) {  
                sign.append("0");  
            }  
            sign.append(hex.toUpperCase());  
        } 
        return sign.toString();  
    }  
    
    
    /**
     * 得到签名
     * @param params 参数集合不含secretkey
     * @param secret 验证接口的secretkey
     * @return
     */
    public static String getSign(Map<String, String> params,String secret)  
    {  
        String sign="";  
        StringBuilder sb = new StringBuilder(); 
        //step1:先对请求参数排序
        Set<String> keyset=params.keySet();  
        TreeSet<String> sortSet=new TreeSet<String>();  
        sortSet.addAll(keyset);  
        Iterator<String> it=sortSet.iterator(); 
        //step2:把参数的key value链接起来 secretkey放在最后面,得到要加密的字符串
        while(it.hasNext())  
        {  
            String key=it.next();  
            String value=params.get(key);  
            sb.append(key).append("=").append(value).append("&");  
        }  
        sb.append("secretkey=").append(secret);  
        byte[] md5Digest;  
        try {  
            //得到Md5加密得到sign
            md5Digest = getMD5Digest(sb.toString());  
            sign = byte2hex(md5Digest);  
        } catch (IOException e) {  
            LOGGER.error("生成签名错误",e);
        }  
        return sign;  
    }  
    
    /**
     * 响应内容
     * @param response
     * @param obj
     */
    public static void print(HttpServletResponse response, Object obj) {
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/json; charset=utf-8");
        PrintWriter out = null;
        try {
            out = response.getWriter();
            Gson gson = new GsonBuilder().serializeNulls().create();
            out.print(gson.toJson(obj));
            out.flush();
            out.close();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (out != null) {
                out.close();
            }
        }
    }
}
 

猜你喜欢

转载自blog.csdn.net/l464513926/article/details/84618238