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.ActionUtil;
|
import com.whyc.util.SerialNumberUtil;
|
import io.swagger.annotations.Api;
|
import io.swagger.annotations.ApiOperation;
|
import org.bouncycastle.math.ec.ECPoint;
|
import org.springframework.boot.system.ApplicationHome;
|
import org.springframework.core.io.ClassPathResource;
|
import org.springframework.util.ClassUtils;
|
import org.springframework.web.bind.annotation.*;
|
|
import javax.annotation.Resource;
|
import java.io.*;
|
import java.math.BigInteger;
|
|
@RequestMapping("license")
|
@RestController
|
@Api(tags = "注册码验证")
|
public class LicenseController {
|
@Resource
|
private LicenseService service;
|
/**
|
* 类加载时初始化sm2的公私钥
|
*/
|
final static ECPoint publicKey = SM2.getPublicKey();
|
final static BigInteger privateKey = SM2.getPrivateKey();
|
|
|
/**
|
* 检验服务器是否注册,是否已存在序列号
|
* 目前需求,校验码发放带上有效期
|
* 在校验的时候,需要校验有效期,首次通过的时候存储到数据库,存储解析后的序列号和有效时长(示例: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());
|
//ActionUtil.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();
|
System.out.println("realPath: "+realPath);
|
BigInteger privKey = x.importPrivateKey(realPath+"config/pri_key.ksm");
|
ECPoint pubKey = x.importPublicKey(realPath+"config/pub_key.ksm");*/
|
|
//旧版本
|
/*String fileDirName=LicenseController.getRealPath("pub_key.ksm");
|
ECPoint pubKey = x.importPublicKey(fileDirName+"/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);
|
byte[] encryptResult = x.encrypt(serialNumber, publicKey);
|
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();
|
//ECPoint pubKey = x.importPublicKey(realPath + "config/pub_key.ksm");
|
/*//旧版本
|
String fileDirName=LicenseController.getRealPath("pri_key.ksm");
|
BigInteger privKey = x.importPrivateKey(fileDirName + "/pri_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, privateKey);
|
//用户只能往小调时间
|
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();
|
}
|
|
|
//将pri_key.ksm。pub_key.ksm文件拷贝至ksm文件下然后读取fileName:/config/pri_key.ksm
|
public static String getRealPath(String fileName){
|
ClassPathResource classPathResource = new ClassPathResource("/config/"+fileName);
|
InputStream inputStream_pub = null;
|
ApplicationHome applicationHome = new ApplicationHome(LicenseController.class);
|
File jarFile = applicationHome.getDir();
|
String fileDirName = jarFile.getParentFile().toString()+ File.separator+"ksm";
|
//String fileDirName = jarFile.toString()+File.separator+"ksm";//打包版本
|
createFile(fileDirName);//创建文件夹ksm
|
try {
|
inputStream_pub = classPathResource.getInputStream();
|
FileOutputStream fos = new FileOutputStream(fileDirName+"/"+fileName);
|
byte[] b = new byte[1024];
|
int length;
|
while((length = inputStream_pub.read(b))>0){
|
fos.write(b,0,length);
|
}
|
inputStream_pub.close();
|
fos.close();
|
} catch (IOException e) {
|
e.printStackTrace();
|
}
|
return fileDirName;
|
}
|
public static void createFile(String pathName) {
|
File dir = new File(pathName);
|
if (!dir.exists()) {// 判断目录是否存在
|
dir.mkdir();
|
}
|
}
|
|
}
|