whyclxw
2022-01-21 b12a528919066862316431e2b6edb16221581385
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
package com.whyc.controller;
 
import com.whyc.dto.Response;
import com.whyc.encryption.ByteConvertUtil;
import com.whyc.encryption.SM2;
import com.whyc.pojo.License;
import com.whyc.service.LicenseService;
import com.whyc.util.AESUtil;
import com.whyc.util.SerialNumberUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.bouncycastle.math.ec.ECPoint;
import org.springframework.util.ClassUtils;
import org.springframework.web.bind.annotation.*;
 
import javax.annotation.Resource;
import java.math.BigInteger;
 
@RequestMapping("license")
@RestController
@Api(tags = "注册码验证")
public class LicenseController {
    @Resource
    private LicenseService service;
 
    /**
     * 检验服务器是否注册,是否已存在序列号
     *  目前需求,校验码发放带上有效期
     *  在校验的时候,需要校验有效期,首次通过的时候存储到数据库,存储解析后的序列号和有效时长(示例:30天),预留字段已经使用时长
     *  因为凭证是针对应用的,所以一个项目数据库中只会保存有一个凭证
     */
    @GetMapping("/checkRegistered")
    @ApiOperation(value = "校验服务器是否注册")
    public Response checkRegistered(){
        return new Response().set(1,true);    //测试环境
        //return service.checkLicenseExpired();
    }
 
    /**
     * 方式一: 获取 序列号的时候,需要在5分钟内输入注册码
     * 方式二: 每次注册码生成,校验通过,放置到数据库中,最新存入数据库的生效,其余都失效,license表存在一个flag字段
     *
     * 当前采用:方式一
     */
 
    /**
     * 获取序列号license
     *
     */
    @GetMapping("/getSerialNumberLicense")
    @ApiOperation(value = "获取序列号license")
    public Response getSerialNumberLicense(){
        //序列号加密 license
        Response model=LicenseController.createLicense(System.currentTimeMillis()+"createTime"+ SerialNumberUtil.getSerialNumber());
        //同时,将序列号生成时间记录到application域中
        //getApplication().setAttribute("serialNumberLicenseTime",System.currentTimeMillis());
        return model;
    }
 
    //获取一个license
    public static Response createLicense(String serialNumber){
        //初始化sm2参数x
        SM2 x = new SM2();
        String realPath = ClassUtils.getDefaultClassLoader().getResource("").getPath();
        BigInteger privKey = x.importPrivateKey(realPath+"config/pri_key.ksm");
        ECPoint pubKey = x.importPublicKey(realPath+"config/pub_key.ksm");
 
        //System.out.println("pubKey "+pubKey);
        /*String origin = "Company: Fuguang Electronic\n"
                + "Project:BTS monitor platform\n"
                + "Licence type:Permanent";*/
        //获取加密列表
        //System.out.println("origin "+origin);
        byte[] encryptResult = x.encrypt(serialNumber, pubKey);
        String encrypt = ByteConvertUtil.bytesToHexString(encryptResult);
        //System.out.println("encrypt:"+encrypt);
        return new Response().set(1,encrypt);
    }
 
    /**
     * 校验license
     * 验证成功添加到数据库web_site.tb_license中
     */
    @GetMapping("/checkSerialNumberLicense")
    @ApiOperation(value = "校验license")
    public Response checkSerialNumberLicense(@RequestParam String license){
        Response model = new Response();
 
        //获取macid是否一致
        boolean res = false;
        //初始化sm2参数x
        SM2 x = new SM2();
        String realPath = ClassUtils.getDefaultClassLoader().getResource("").getPath();
        BigInteger privKey = x.importPrivateKey(realPath + "config/pri_key.ksm");
        ECPoint pubKey = x.importPublicKey(realPath + "config/pub_key.ksm");
        String origin = "Company: Fuguang Electronic\n"
                + "Project:BTS monitor platform\n"
                + "Licence duration:";
        //获取解密后license,附带校验license编码格式
        String decryptResult = null;
        byte[] bytes = ByteConvertUtil.hexToByteArray(license);
        decryptResult = x.decrypt(bytes, privKey);
        //用户只能往小调时间
        String[] split1 = decryptResult.split("machineCode:");
        Long registerCodeTime = Long.valueOf(split1[0]);
        Long machineCodeCreateTime = Long.valueOf(split1[1].split("createTime")[0]);
        //检验解码后license的值是否正确
        String serialNumberStr = SerialNumberUtil.getSerialNumber() + "@@" + origin;
        res = decryptResult.contains(serialNumberStr);
        if (res) {
            //校验license输入时间是否超过5分钟,5分钟内则存储到数据库中
            long currentTimeMillis = System.currentTimeMillis();
            //long serialNumberLicenseTime = (long) getApplication().getAttribute("serialNumberLicenseTime");
            //if(currentTimeMillis-serialNumberLicenseTime>=5*60*1000){
            if (currentTimeMillis - machineCodeCreateTime >= 5 * 60 * 1000) {
                model.setCode(1);
                model.setData(false);
                model.setMsg("注册码获取及输入超过5分钟,请重新获取注册码");
            } else if (registerCodeTime > currentTimeMillis) {
                model.setCode(1);
                model.setData(false);
                model.setMsg("系统时间不正常,请检查");
            } else {
                model.setCode(1);
                model.setData(true);
                model.setMsg("注册码校验成功");
            }
            //model.setData(decryptResult);
            //model.setMsgN(serialNumberStr);
            double duration = Integer.parseInt(decryptResult.split("duration:")[1]);
            License data = new License();
            data.setSerialNumber(SerialNumberUtil.getSerialNumber());
            //duration和TimeInUse加密存入数据库
            String durationEncrypt = AESUtil.aesEncrypt(String.valueOf(duration));
            data.setDuration(durationEncrypt);
 
            String timeInUseEncrypt = AESUtil.aesEncrypt(String.valueOf(0));
            data.setTimeInUse(timeInUseEncrypt);
            //将序列号,有效期 添加入license表
            service.add(data);
        } else {
            model.setCode(1);
            model.setData(false);
            model.setMsg("验证失败");
            //model.setData(decryptResult);
            //model.setMsgN(serialNumberStr);
        }
        model.setCode(1);   //测试环境
        model.setData(true);
        return model;
    }
 
    @PostMapping("/time2DeadLine")
    @ApiOperation(value = "有效期检验")
    public Response time2DeadLine(){
        return service.time2DeadLine();
    }
 
 
 
}