接口签名(sign)

一版

package com.toltech.phatent.test;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.toltech.phatent.commons.bean.ReadedReq;
import com.toltech.phatent.commons.utils.CryptoUtils;
import com.toltech.phatent.commons.utils.HttpUtils;
import org.apache.commons.lang.StringUtils;
import org.junit.Test;

import java.util.SortedMap;
import java.util.TreeMap;

/**
 * Created by wanggs on 2017/9/28.
 */
public class ReadedCase {
    @Test
    public void readedTest() {
        ReadedReq readedReq = new ReadedReq();
        readedReq.setId(1);
        readedReq.setRecipients("1");
        JSONObject object = (JSONObject) JSON.toJSON(readedReq);
        SortedMap<String, String> map = new TreeMap<>();
        for (String key : object.keySet()) {
            if (key.equals("sign")) {
                continue;
            }
            String value = object.getString(key);
            if (StringUtils.isNotBlank(value))
            map.put(key, value);
        }
        System.out.println(map);
        String sign = CryptoUtils.getSignature(map);
        object.put("sign", sign);
        String jsonString = object.toJSONString();
        System.out.println(jsonString);
        String url = "http://localhost:8080/phatent-front/readed/create.do";
        String result = HttpUtils.postStringBody(url, jsonString);
        System.out.println(result);
    }
}

二版

package com.toltech.phatent.test;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;

import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.junit.Test;

import com.alibaba.fastjson.JSONObject;
import com.toltech.phatent.commons.utils.CryptoUtils;
import com.toltech.phatent.commons.utils.HttpUtils;

/**
 * Created by wanggs on 2017/9/28.
 */
public class ReadedCase {
    @Test
    public void readedTest() {
        SortedMap<String, String> map = new TreeMap<String, String>();
        map.put("noticeId","1");
        map.put("memberId","2");
        String sign = CryptoUtils.getSignature(map);
        System.out.println(sign);
        map.put("sign", sign);
        List<NameValuePair> nameValues = new ArrayList<NameValuePair>();
        for(Map.Entry<String, String> entry : map.entrySet()){
            nameValues.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
        }
        System.out.println("nameValues=========>>"+nameValues);
        String url = "http://dev.dz100199.com:9091/readed/create.do";
        JSONObject result = HttpUtils.getHttpJson(url, nameValues);
        System.out.println(result);

    }
}

签收加密

package com.toltech.phatent.commons.utils;

import java.security.MessageDigest;
import java.util.Map.Entry;
import java.util.SortedMap;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.IvParameterSpec;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.toltech.framework.commons.binary.Base64;
import com.toltech.phatent.commons.consts.ConfConst;

/**
 * CryptoUtils
 * @author 
 * @version 1.0
 * @since 2017年8月18日下午3:04:26
 */
public class CryptoUtils {
    private static final Logger LOGGER = LoggerFactory.getLogger(CryptoUtils.class);
    private static SecretKey KEY;
    private static IvParameterSpec IV;
    
    static{
        try {
            int keyLength = 8;
            String desKey = ConfigUtils.getValue(ConfConst.DES_KEY_CONF);
            if(desKey.length() > keyLength){
                desKey = desKey.substring(0, keyLength);
            }
            byte[] rgbKey = desKey.getBytes(ConfConst.DEFAULT_CHARSET);
            String desIv = ConfigUtils.getValue(ConfConst.DES_IV_CONF);
            if(desIv.length() > keyLength){
                desIv = desIv.substring(0, keyLength);
            }
            byte[] rgbIV = desIv.getBytes(ConfConst.DEFAULT_CHARSET);
            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES"); 
            DESKeySpec desKeySpec = new DESKeySpec(rgbKey);
            KEY = keyFactory.generateSecret(desKeySpec); 
            IV = new IvParameterSpec(rgbIV);
        } catch (Exception e) {
            LOGGER.error("encrypt key and iv init error.", e);
        }
    }
    
    public static String encrypt(String str) {
        if(StringUtils.isBlank(str))
            return null;
        if(KEY == null || IV == null)
            return null;
        byte[] byteArray = null;
        try {
            byte[] strByteArray = str.getBytes(ConfConst.DEFAULT_CHARSET);
            Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
            cipher.init(Cipher.ENCRYPT_MODE, KEY, IV);
            byteArray = cipher.doFinal(strByteArray);
        } catch (Exception e) {
            LOGGER.error("encrypt error.", e);
        }
        return Base64.encode(byteArray);
    }
    
    public static String decrypt(String str) {
        if(StringUtils.isBlank(str))
            return null;
        if(KEY == null || IV == null)
            return null;
        byte[] byteArray;
        String result = null;
        try {
            Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
            cipher.init(Cipher.DECRYPT_MODE, KEY, IV);
            byteArray = cipher.doFinal(Base64.decode(str));
            result = new String(byteArray, ConfConst.DEFAULT_CHARSET);
        } catch (Exception e) {
            LOGGER.error("decrypt error.", e);
        }
        return result;
    }
    
    /**
     * 参数DM5加密并Base64转码加密
     * @param str
     * @return
     */
    public static String md5AndBase64(String str) {
        return Base64.encode(md5Encrypt(str));
    }

    /**
     * 参数DM5签名字节码
     * @param encryptStr
     * @return
     */
    private static byte[] md5Encrypt(String encryptStr) {
        try {
            MessageDigest md5 = MessageDigest.getInstance("MD5");
            md5.update(encryptStr.getBytes("utf8"));
            return md5.digest();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    
    public static String getSignature(SortedMap<String, String> map){
        if(map != null && map.size() > 0){
            StringBuilder builder = new StringBuilder();
            for(Entry<String, String> entry : map.entrySet()){
                if(entry.getKey().equals("sign")){
                    continue;
                }
                builder.append(entry.getKey()+"="+entry.getValue());
                builder.append("&");
            }
            builder.append("key="+ConfigUtils.getValue(ConfConst.MD5_KEY_CONF));
            String signString = builder.toString();
            LOGGER.debug("sign string :{}", signString);
            String result = md5AndBase64(signString);
            LOGGER.debug("data md5AndBase64 result:{}", result);
            return result;
        }
        return null;
    }
}

验证签名

package com.toltech.phatent.web.action;

import javax.annotation.Resource;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.toltech.phatent.commons.bean.ReadedReq;
import com.toltech.phatent.commons.bean.ResultBean;
import com.toltech.phatent.commons.enums.ResultStatu;
import com.toltech.phatent.commons.utils.CryptoUtils;
import com.toltech.phatent.persistence.entity.custom.Member;
import com.toltech.phatent.persistence.entity.front.Notice;
import com.toltech.phatent.persistence.entity.front.Readed;
import com.toltech.phatent.service.custom.MemberServiceBean;
import com.toltech.phatent.service.notice.NoticeServiceBean;
import com.toltech.phatent.service.readed.ReadedServiceBean;
import com.toltech.phatent.web.core.GenericAction;

import java.util.SortedMap;
import java.util.TreeMap;

/**
 * Created by 
 * 消息阅读接口
 */
@Controller
@RequestMapping("readed")
public class ReadedAction extends GenericAction {
    private static final long serialVersionUID = 1L;
    private static Logger logger = LoggerFactory.getLogger(ReadedAction.class);
    @Resource
    private NoticeServiceBean noticeServiceBean;
    @Resource
    private MemberServiceBean memberServiceBean;
    @Resource
    private ReadedServiceBean readedServiceBean;

    @ResponseBody
    @RequestMapping(CREATE)
    public JSONObject readed(@RequestBody String body) {
        ResultBean<Void> result = null;
        ReadedReq req = null;
        if (StringUtils.isNotBlank(body)) {
            // 验证签名
            JSONObject resultSign = checkSign(body);
            if (resultSign != null) return resultSign;
            // 反序列化json对象
            req = JSON.parseObject(body,ReadedReq.class);
            // 校验参数
            JSONObject jsonObject = checkReq(req);
            if (jsonObject != null)
                return jsonObject;
            // 收件人不为空
            if (StringUtils.isNotBlank(req.getRecipients())) {
                Member member = memberServiceBean.findByGuidCode(req.getRecipients());
                Notice notice = noticeServiceBean.findByReceiveId(req.getId());
                if (member != null) {
                    Readed read = new Readed();
                    read.setMemberId(member.getId());
                    read.setNoticeId(notice.getId());
                    // 保存
                    readedServiceBean.save(read);
                    result = new ResultBean<Void>(ResultStatu.X0000, null, "处理成功");
                    return (JSONObject) JSON.toJSON(result);
                }
                result = new ResultBean<Void>(ResultStatu.X1004, null, "会员不存在");
                return (JSONObject) JSON.toJSON(result);
            }
        }
        result = new ResultBean<Void>(ResultStatu.X1000, null, "参数为空");
        return (JSONObject) JSON.toJSON(result);
    }

    /**
     * 验证签名
     * @param body
     * @return
     */
    private JSONObject checkSign(@RequestBody String body) {
        ResultBean<Void> result;
        JSONObject paramObject = JSON.parseObject(body);
        if (paramObject == null) {
            result = new ResultBean<Void>(ResultStatu.X1001, null, "参数格式错误");
            return (JSONObject) JSON.toJSON(result);
        }
        SortedMap<String, String> paramMap = new TreeMap<String, String>();
        String sign = null;
        for (String key : paramObject.keySet()) {
            if ("sign".equals(key)) {
                sign = paramObject.getString(key);
                continue;
            }
            paramMap.put(key, paramObject.getString(key));
        }
        logger.info("map >>>>>>>>>>> {}", paramMap);
        if (StringUtils.isBlank(sign)) {
            result = new ResultBean<Void>(ResultStatu.X1000, null, "参数签名为空");
            return (JSONObject) JSON.toJSON(result);
        }
        // 生成签名
        String paramSign = CryptoUtils.getSignature(paramMap);
        logger.info("sign>>>>>>>>>>>{}, encrypt sign>>>>>>>>>>{}", sign, paramSign);
        // 判断签名是否一致
        if (!paramSign.equals(sign)) {
            result = new ResultBean<Void>(ResultStatu.X1000, null, "参数签名错误");
            return (JSONObject) JSON.toJSON(result);
        }
        return null;
    }

    /**
     * 校验参数
     * @param readed
     * @return
     */
    private JSONObject checkReq(ReadedReq readed) {
        ResultBean<Void> result;
        if (readed.getId() == null) {
            result = new ResultBean<Void>(ResultStatu.X1000, null, "消息id为空");
            return (JSONObject) JSON.toJSON(result);
        }
        Notice notice = noticeServiceBean.findByReceiveId(readed.getId());
        if (notice == null) {
            result = new ResultBean<Void>(ResultStatu.X1004, null, "数据不存在");
            return (JSONObject) JSON.toJSON(result);
        }
        return null;
    }
}

验证签名已经在拦截器中处理

package com.toltech.phatent.web.action;

import java.util.ArrayList;
import java.util.List;

import javax.annotation.Resource;

import org.apache.commons.lang.StringUtils;
import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.toltech.phatent.commons.bean.ReadedReq;
import com.toltech.phatent.commons.bean.ResultBean;
import com.toltech.phatent.commons.consts.FrontConst;
import com.toltech.phatent.commons.enums.BasicStatu;
import com.toltech.phatent.commons.enums.ResultStatu;
import com.toltech.phatent.commons.utils.ConfigUtils;
import com.toltech.phatent.commons.utils.HttpUtils;
import com.toltech.phatent.commons.utils.SecureUtils;
import com.toltech.phatent.persistence.entity.custom.Member;
import com.toltech.phatent.persistence.entity.front.Notice;
import com.toltech.phatent.persistence.entity.front.Readed;
import com.toltech.phatent.service.custom.MemberServiceBean;
import com.toltech.phatent.service.notice.NoticeServiceBean;
import com.toltech.phatent.service.readed.ReadedServiceBean;
import com.toltech.phatent.web.core.GenericAction;

/**
 * Created by wanggs on 2017/9/15.
 * 消息阅读接口
 */
@Controller
@RequestMapping("readed")
public class ReadedAction extends GenericAction {
    private static final long serialVersionUID = 1L;
    private static Logger logger = LoggerFactory.getLogger(ReadedAction.class);
    @Resource
    private NoticeServiceBean noticeServiceBean;
    @Resource
    private MemberServiceBean memberServiceBean;
    @Resource
    private ReadedServiceBean readedServiceBean;

    @ResponseBody
    @RequestMapping(CREATE)
    public JSONObject readed(ReadedReq form) {
        ResultBean<Void> result = null;
        // 校验参数
        if (form.getNoticeId() == null) {
            result = new ResultBean<Void>(ResultStatu.X1000, null, "消息id为空");
            return (JSONObject) JSON.toJSON(result);
        }
        Integer receiveId = form.getReceiveId();
        Integer noticeId = form.getNoticeId();
        Notice notice = noticeServiceBean.find(noticeId);
        if (notice == null || notice.getStatu() == null || notice.getStatu() != BasicStatu.ENABLED) {
            result = new ResultBean<Void>(ResultStatu.X1004, null, "数据不存在");
            return (JSONObject) JSON.toJSON(result);
        }
        Integer memberId = form.getMemberId();
        // 收件人不为空
        if (memberId != null) {
            Integer readedId = readedServiceBean.findId(memberId, noticeId);
            if(readedId == null){
                 Readed read = new Readed();
                 read.setMemberId(memberId);
                 read.setNoticeId(noticeId);
                 readedServiceBean.save(read);
            }
            if(receiveId != null && receiveId.intValue() > 0 && notice.getReceiveId().intValue() == receiveId.intValue()){
                Member member = memberServiceBean.find(memberId);
                if(member != null && StringUtils.isNotBlank(member.getGuidCode())){
                    long timeMillis = System.currentTimeMillis();
                    String sign = SecureUtils.md5Encrypt(FrontConst.DZ_KEY+timeMillis+FrontConst.DZ_SECRET,  null);
                    logger.debug("params md5 sign >>>>>>>>>{}",sign);
                    String url = ConfigUtils.getValue(FrontConst.DZ_EDU_NOTICE_CALLBACK_URL_CONF);
                    List<NameValuePair> params = new ArrayList<NameValuePair>();
                    params.add(new BasicNameValuePair("id", String.valueOf(receiveId)));
                    params.add(new BasicNameValuePair("key", FrontConst.DZ_KEY));
                    params.add(new BasicNameValuePair("t", String.valueOf(timeMillis)));
                    params.add(new BasicNameValuePair("s", sign));
                    params.add(new BasicNameValuePair("guid", member.getGuidCode()));
                    JSONObject object = HttpUtils.getHttpJson(url, params);
                    logger.debug("callback read notice result>>>>>>>>>{}",object);
                }
            }
            result = new ResultBean<Void>(ResultStatu.X0000, null, "处理成功");
            return (JSONObject) JSON.toJSON(result);
        }
        result = new ResultBean<Void>(ResultStatu.X1004, null, "会员不存在");
        return (JSONObject) JSON.toJSON(result);
    }
}

拦截器

package com.toltech.phatent.web.inteceptor;


import java.util.SortedMap;

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

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import com.alibaba.fastjson.JSON;
import com.toltech.phatent.commons.bean.ResultBean;
import com.toltech.phatent.commons.enums.ResultStatu;
import com.toltech.phatent.commons.utils.CommonUtils;
import com.toltech.phatent.commons.utils.CryptoUtils;



@Service
public class AccessInterceptor extends HandlerInterceptorAdapter{
    private static final Logger LOGGER = LoggerFactory.getLogger(AccessInterceptor.class);
    
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        response.setCharacterEncoding("utf-8");
        HandlerMethod method = (HandlerMethod) handler;
        LOGGER.debug("{}",method.getMethod());
        if(request.getContentLength() > 0){
            return super.preHandle(request, response, handler);
        }
        String sign = request.getParameter("sign");
        if(StringUtils.isBlank(sign)){
            ResultBean<Void> result = new ResultBean<Void>(ResultStatu.X1000, null, "签名参数为空");
            response.getWriter().print(JSON.toJSONString(result));
            return false;
        }
        SortedMap<String, String> paramMap = CommonUtils.getParametersMap(request);
        String paramSign = CryptoUtils.getSignature(paramMap);
        if(!sign.equals(paramSign)){
            ResultBean<Void> result = new ResultBean<Void>(ResultStatu.X1001, null, "参数签名不正确");
            response.getWriter().print(JSON.toJSONString(result));
            return false;
        }
        return super.preHandle(request, response, handler);
    }
    
     public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
            super.postHandle(request, response, handler, modelAndView);
         }
}

image.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容