当前位置:网站首页>Security design verification of API interface: ticket, signature, timestamp

Security design verification of API interface: ticket, signature, timestamp

2022-07-06 10:12:00 Wu soul lv95 blue silver grass

One . background

1. Docking with the front end API Interface , If it is captured by a third party and maliciously tampers with parameters , It could lead to data leakage , It can even be tampered with

2. Interface with third-party companies , If the third party gets your interface document , But the interface does not have security verification , Is very unsafe

I'm mainly around timestamps ,token, The signature has three parts to guarantee API Interface security

Two . Request process

1. After the user successfully logs in to the site , The server will return a token, This parameter must be included in any operation of the user , You can put this parameter directly into header in .

2. The client uses the parameters and token Generate a signature sign, Send it to the server as a parameter , The server is using the same method to generate sign Check for tampering .

3. But there are still problems , May be malicious unrestricted access , At this point, we need to introduce a timestamp parameter , If the timeout is invalid .

4. The server needs to token, Signature , Time stamp for verification , Only token It works , The timestamp did not time out , The signature is valid to be released .

Concept :

(1) Open interface

There are no restrictions on , Simple and crude access , This kind of interface is generally used in open application platform , Check the weather , Check express , As long as you input the correct parameters, call , You can get the information you need , We can change the parameter value at will .

(2)Token Certification acquisition

After the user logs in successfully , Will get a ticket value , This parameter is required for any subsequent interface access . We put it in redis Inside , Valid for 10 minute , stay ticket About to time out , Life without perception . Extend the use time , If the user doesn't do anything in a period of time , You need to log back into the system .

(3)Sign Signature

Put all the parameters together , After adding the system secret key , Conduct MD5 The calculation generates a sign Signature , Prevent parameters from being tampered maliciously , The background generates the secret key in the same way , Make a signature comparison .

(4) Repeat the visit

Introduce a timestamp parameter , Ensure that the interface is only valid for one minute , Need to be consistent with client time .

(5) Interceptor

Each request comes with these three parameters , We all need to verify , Only when all three parameters meet our requirements , To allow data to be returned or manipulated .

 

3、 ... and . Specific code implementation

1. Write to get tiket The interface of

    /**
     *  obtain tiket
     * @param receiveRequest
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/gettiket",method = RequestMethod.POST)
    public  String gettiket(@RequestBody String data){
        String result = "";
        String msg = "";
        try{
            log.info("gettiket, The parameter for ==="+data);

            JdbcTemplate jdbcTemplate = new JdbcTemplate();
            String userTocken = UUID.randomUUID().toString();
            //cache.put(userTocken, userMap);// Database mode or redis The way , Here we use database 
            String insert_user_token_sql = "insert into user_token(pk_user_token,userid,user_token) VALUES (?,?,?)";
            long pk_user_token = KeyUtils.nextId();// Primary key 

            jdbcTemplate.executeUpdate(insert_user_token_sql, new Object[]{
                    pk_user_token,"111",userTocken
            });
            result = userTocken;
            msg = "{\"success\" : true,\"errorCode\" : \"200\", \"errorMsg\" : \" Query complete \", \"tiket\" :" +result + "}";
            log.info("msg===="+msg);
            return msg;
        }catch(Exception e){
            msg = "{\"success\" : true,\"errorCode\" : \"500\", \"errorMsg\" : \" Query complete \", \"data\" :" +e + "}";
            return msg;
        }


    }

2. Server side validation

Main program entry

        Map<String, String> paramMap = new HashMap<>();
        String time = DateUtils.formatDate("yyyy-MM-dd HH:mm:ss.SSS");
        paramMap.put("time", time);
        String ticket = "056a3d29-eed3-4ee9-80aa-c03321d5302f";
        paramMap.put("ticket", ticket);//userTock For the first time I ask for your single point url From time to time userTocken
        String serviceCode = "cs_demo";//  The key corresponding to the target system 
        String sign = null;
        try {
            sign = SignUtils.sing(paramMap, serviceCode, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        log.info("sign==="+sign);
        CheckPerService checkPerService= new CheckPerService();
        Boolean istrue = checkPerService.TicketSignAndTime( ticket, sign, time, serviceCode);
        log.info("istrue==="+istrue);

Tool class SignUtils

package tcc.test.utill;

import org.apache.log4j.Logger;
import org.springframework.util.DigestUtils;
import java.io.UnsupportedEncodingException;
import java.util.*;

public class SignUtils {
    private static final Logger a = Logger.getRootLogger();

    public SignUtils() {
    }

    public static String getContent(Map params) {
        List keys = new ArrayList(params.keySet());
        Collections.sort(keys);
        String prestr = "";
        boolean first = true;

        for(int i = 0; i < keys.size(); ++i) {
            String key = (String)keys.get(i);
            if (!"sign".equals(key) && !"_r".equals(key) && !"_result_type".equals(key) && !"_".equals(key)) {
                String value = String.valueOf(params.get(key));
                if (value != null && value.trim().length() != 0) {
                    if (first) {
                        prestr = prestr + key + "=" + value;
                        first = false;
                    } else {
                        prestr = prestr + "&" + key + "=" + value;
                    }
                }
            }
        }

        a.info(" Encrypted string :" + prestr);
        return prestr;
    }


    public static String sing(Map Params, String key, String charset) throws UnsupportedEncodingException {
        String signStr = null;
        signStr = DigestUtils.md5DigestAsHex((getContent(Params) + key).getBytes(charset));
        return signStr;
    }


    public static void main(String[] args) throws Exception {
        Map paramMap = new HashMap<String,String>();
        paramMap.put("name","tcc");
        paramMap.put("age","24");
        String serviceCode = "siruinet";
        String sing = SignUtils.sing(paramMap, serviceCode, "UTF-8");
        System.out.println(sing);



    }
}

Permission verification tool class

package tcc.test.utill;

import com.alibaba.druid.util.StringUtils;
import com.util.FieldList;
import jos.engine.core.jdbc.JdbcTemplate;
import jos.engine.des.util.DesEncryptUtils;
import org.apache.log4j.Logger;

import java.util.HashMap;
import java.util.Map;

/**
 * Copyright (C) @2022
 *
 * @author: tcc
 * @version: 1.0
 * @date: 2022/1/31
 * @time: 2:08
 * @description:
 */
public class CheckPerService{
    private static final Logger log = Logger.getRootLogger();

    /*
     Interface permission verification method 1
    ticket: Notes 
    sign: Signature 
    time: Time stamp 
    serviceCode: Service code */
    public static boolean TicketSignAndTime(String ticket, String sign, String time, String serviceCode){
        time = time;
        ticket = ticket;
        sign = sign;
        Map<String, String> paramMap = new HashMap<>();
        paramMap.put("time", time);
        paramMap.put("ticket", ticket);//ticket Get for the first call ticket Interface data 
        serviceCode = serviceCode;//  The key corresponding to the target system 
        String qm = DesEncryptUtils.sing(paramMap, serviceCode, "UTF-8");
        log.info("qm==="+qm);
        if (!StringUtils.equals(sign, qm)) { // Key verification error 
            log.info(" Incorrect signature ");
            return false;
        }
        log.info(" The signature is correct ");
        JdbcTemplate jdbcTemplate = new JdbcTemplate();
        String qr_user_token_sql = "select count(1) as count from user_token where user_token = ?";// Later it will be changed to redis
        FieldList file_token = jdbcTemplate.queryField(qr_user_token_sql, new Object[]{ ticket });
        int count = Integer.parseInt(file_token.get("count"));
        if(count<1){
            return false;
        }
        return true;
    }

        /*
     Interface permission verification method 2
    name: user name 
    pwd: password 
     */
    public static boolean UnmAndPwd(String name,String pwd){
        JdbcTemplate jdbcTemplate = new JdbcTemplate("mzdb");
        String qr_user_token_sql = "select count(1) as count from bd_user where USERNAME = ? and USERPASS = ?";// Later it will be changed to redis
        FieldList file_token = jdbcTemplate.queryField(qr_user_token_sql, new Object[]{ name,pwd });
        int count = Integer.parseInt(file_token.get("count"));
        if(count<1){
            return false;
        }
        return true;

    }





}

 

原网站

版权声明
本文为[Wu soul lv95 blue silver grass]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/02/202202131725425838.html