添加设备激活相关模块,设计 Bean 的属性。
This commit is contained in:
+11
@@ -0,0 +1,11 @@
|
||||
package com.sunyar.cisd;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
public class DeviceActivationApplication {
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(DeviceActivationApplication.class, args);
|
||||
}
|
||||
}
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
package com.sunyar.cisd;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/device")
|
||||
public class DeviceActivationController {
|
||||
|
||||
@Autowired
|
||||
private DeviceActivationService deviceActivationService;
|
||||
|
||||
@PostMapping("/active")
|
||||
public DeviceActivationResponse activate(@RequestBody DeviceActivationRequest request) {
|
||||
try {
|
||||
if (request.getParams() == null) {
|
||||
return DeviceActivationResponse.error("参数不能为空", "1001");
|
||||
}
|
||||
|
||||
DeviceActivationRequest.Params params = request.getParams();
|
||||
String concatenatedParams = params.toConcatenatedString();
|
||||
String calculatedHash = deviceActivationService.calculateSm3Hash(concatenatedParams);
|
||||
|
||||
String deviceActivationPublicKey = deviceActivationService.generateDeviceActivationPublicKey();
|
||||
String deviceActivationResult = deviceActivationService.signWithSm2Pkcs1(calculatedHash, deviceActivationPublicKey);
|
||||
|
||||
DeviceActivationResponse.Data data = new DeviceActivationResponse.Data();
|
||||
data.setHash(calculatedHash);
|
||||
data.setDeviceActivationPublicKey(deviceActivationPublicKey);
|
||||
data.setDeviceActivationResult(deviceActivationResult);
|
||||
|
||||
return DeviceActivationResponse.ok("设备激活成功", data);
|
||||
} catch (Exception e) {
|
||||
return DeviceActivationResponse.error("设备激活失败: " + e.getMessage(), "1002");
|
||||
}
|
||||
}
|
||||
}
|
||||
+126
@@ -0,0 +1,126 @@
|
||||
package com.sunyar.cisd;
|
||||
|
||||
public class DeviceActivationRequest {
|
||||
private Params params;
|
||||
private String hash;
|
||||
|
||||
public DeviceActivationRequest() {
|
||||
}
|
||||
|
||||
public Params getParams() {
|
||||
return params;
|
||||
}
|
||||
|
||||
public void setParams(Params params) {
|
||||
this.params = params;
|
||||
}
|
||||
|
||||
public String getHash() {
|
||||
return hash;
|
||||
}
|
||||
|
||||
public void setHash(String hash) {
|
||||
this.hash = hash;
|
||||
}
|
||||
|
||||
public static class Params {
|
||||
private String userId;
|
||||
private String credential;
|
||||
private String deviceActivationCode;
|
||||
private String deviceSerialNumber;
|
||||
private String deviceFingerprintJson;
|
||||
private String deviceSignature;
|
||||
private String devicePublicKey;
|
||||
private String timestamp;
|
||||
private String nonce;
|
||||
|
||||
public Params() {
|
||||
}
|
||||
|
||||
public String getUserId() {
|
||||
return userId;
|
||||
}
|
||||
|
||||
public void setUserId(String userId) {
|
||||
this.userId = userId;
|
||||
}
|
||||
|
||||
public String getCredential() {
|
||||
return credential;
|
||||
}
|
||||
|
||||
public void setCredential(String credential) {
|
||||
this.credential = credential;
|
||||
}
|
||||
|
||||
public String getDeviceActivationCode() {
|
||||
return deviceActivationCode;
|
||||
}
|
||||
|
||||
public void setDeviceActivationCode(String deviceActivationCode) {
|
||||
this.deviceActivationCode = deviceActivationCode;
|
||||
}
|
||||
|
||||
public String getDeviceSerialNumber() {
|
||||
return deviceSerialNumber;
|
||||
}
|
||||
|
||||
public void setDeviceSerialNumber(String deviceSerialNumber) {
|
||||
this.deviceSerialNumber = deviceSerialNumber;
|
||||
}
|
||||
|
||||
public String getDeviceFingerprintJson() {
|
||||
return deviceFingerprintJson;
|
||||
}
|
||||
|
||||
public void setDeviceFingerprintJson(String deviceFingerprintJson) {
|
||||
this.deviceFingerprintJson = deviceFingerprintJson;
|
||||
}
|
||||
|
||||
public String getDeviceSignature() {
|
||||
return deviceSignature;
|
||||
}
|
||||
|
||||
public void setDeviceSignature(String deviceSignature) {
|
||||
this.deviceSignature = deviceSignature;
|
||||
}
|
||||
|
||||
public String getDevicePublicKey() {
|
||||
return devicePublicKey;
|
||||
}
|
||||
|
||||
public void setDevicePublicKey(String devicePublicKey) {
|
||||
this.devicePublicKey = devicePublicKey;
|
||||
}
|
||||
|
||||
public String getTimestamp() {
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
public void setTimestamp(String timestamp) {
|
||||
this.timestamp = timestamp;
|
||||
}
|
||||
|
||||
public String getNonce() {
|
||||
return nonce;
|
||||
}
|
||||
|
||||
public void setNonce(String nonce) {
|
||||
this.nonce = nonce;
|
||||
}
|
||||
|
||||
public String toConcatenatedString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
if (userId != null) sb.append(userId);
|
||||
if (credential != null) sb.append(credential);
|
||||
if (deviceActivationCode != null) sb.append(deviceActivationCode);
|
||||
if (deviceSerialNumber != null) sb.append(deviceSerialNumber);
|
||||
if (deviceFingerprintJson != null) sb.append(deviceFingerprintJson);
|
||||
if (deviceSignature != null) sb.append(deviceSignature);
|
||||
if (devicePublicKey != null) sb.append(devicePublicKey);
|
||||
if (timestamp != null) sb.append(timestamp);
|
||||
if (nonce != null) sb.append(nonce);
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
+94
@@ -0,0 +1,94 @@
|
||||
package com.sunyar.cisd;
|
||||
|
||||
public class DeviceActivationResponse {
|
||||
private String status;
|
||||
private String msg;
|
||||
private String code;
|
||||
private Data data;
|
||||
|
||||
public DeviceActivationResponse() {
|
||||
}
|
||||
|
||||
public static DeviceActivationResponse ok(String msg, Data data) {
|
||||
DeviceActivationResponse response = new DeviceActivationResponse();
|
||||
response.status = "ok";
|
||||
response.msg = msg;
|
||||
response.code = "0";
|
||||
response.data = data;
|
||||
return response;
|
||||
}
|
||||
|
||||
public static DeviceActivationResponse error(String msg, String code) {
|
||||
DeviceActivationResponse response = new DeviceActivationResponse();
|
||||
response.status = "error";
|
||||
response.msg = msg;
|
||||
response.code = code;
|
||||
response.data = null;
|
||||
return response;
|
||||
}
|
||||
|
||||
public String getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(String status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public String getMsg() {
|
||||
return msg;
|
||||
}
|
||||
|
||||
public void setMsg(String msg) {
|
||||
this.msg = msg;
|
||||
}
|
||||
|
||||
public String getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public void setCode(String code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public Data getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public void setData(Data data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public static class Data {
|
||||
private String hash;
|
||||
private String deviceActivationPublicKey;
|
||||
private String deviceActivationResult;
|
||||
|
||||
public Data() {
|
||||
}
|
||||
|
||||
public String getHash() {
|
||||
return hash;
|
||||
}
|
||||
|
||||
public void setHash(String hash) {
|
||||
this.hash = hash;
|
||||
}
|
||||
|
||||
public String getDeviceActivationPublicKey() {
|
||||
return deviceActivationPublicKey;
|
||||
}
|
||||
|
||||
public void setDeviceActivationPublicKey(String deviceActivationPublicKey) {
|
||||
this.deviceActivationPublicKey = deviceActivationPublicKey;
|
||||
}
|
||||
|
||||
public String getDeviceActivationResult() {
|
||||
return deviceActivationResult;
|
||||
}
|
||||
|
||||
public void setDeviceActivationResult(String deviceActivationResult) {
|
||||
this.deviceActivationResult = deviceActivationResult;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
package com.sunyar.cisd;
|
||||
|
||||
import org.bouncycastle.crypto.digests.SM3Digest;
|
||||
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
||||
import org.bouncycastle.util.encoders.Hex;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.Security;
|
||||
import java.security.Signature;
|
||||
import java.util.Base64;
|
||||
|
||||
@Service
|
||||
public class DeviceActivationService {
|
||||
|
||||
private static final String PROVIDER = "BC";
|
||||
private static final String SIGNATURE_ALGO = "SM3withSM2";
|
||||
|
||||
static {
|
||||
if (Security.getProvider(PROVIDER) == null) {
|
||||
Security.addProvider(new BouncyCastleProvider());
|
||||
}
|
||||
}
|
||||
|
||||
public String calculateSm3Hash(String data) {
|
||||
SM3Digest digest = new SM3Digest();
|
||||
byte[] input = data.getBytes(StandardCharsets.UTF_8);
|
||||
digest.update(input, 0, input.length);
|
||||
byte[] hash = new byte[digest.getDigestSize()];
|
||||
digest.doFinal(hash, 0);
|
||||
return Hex.toHexString(hash);
|
||||
}
|
||||
|
||||
public String signWithSm2Pkcs1(String data, String privateKeyBase64) {
|
||||
try {
|
||||
byte[] keyBytes = Base64.getDecoder().decode(privateKeyBase64);
|
||||
java.security.spec.PKCS8EncodedKeySpec keySpec = new java.security.spec.PKCS8EncodedKeySpec(keyBytes);
|
||||
java.security.KeyFactory keyFactory = java.security.KeyFactory.getInstance("EC", PROVIDER);
|
||||
java.security.PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
|
||||
|
||||
Signature signature = Signature.getInstance(SIGNATURE_ALGO, PROVIDER);
|
||||
signature.initSign(privateKey);
|
||||
signature.update(data.getBytes(StandardCharsets.UTF_8));
|
||||
byte[] signatureBytes = signature.sign();
|
||||
return Base64.getEncoder().encodeToString(signatureBytes);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("SM2签名失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
public String generateDeviceActivationPublicKey() {
|
||||
try {
|
||||
java.security.KeyPairGenerator keyGen = java.security.KeyPairGenerator.getInstance("EC", PROVIDER);
|
||||
keyGen.initialize(256);
|
||||
java.security.KeyPair keyPair = keyGen.generateKeyPair();
|
||||
return Base64.getEncoder().encodeToString(keyPair.getPublic().getEncoded());
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("生成设备激活公钥失败", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
package com.sunyar.cisd;
|
||||
|
||||
//TIP 要<b>运行</b>代码,请按 <shortcut actionId="Run"/> 或
|
||||
// 点击装订区域中的 <icon src="AllIcons.Actions.Execute"/> 图标。
|
||||
public class Main {
|
||||
public static void main(String[] args) {
|
||||
//TIP 当文本光标位于高亮显示的文本处时按 <shortcut actionId="ShowIntentionActions"/>
|
||||
// 查看 IntelliJ IDEA 建议如何修正。
|
||||
System.out.printf("Hello and welcome!");
|
||||
|
||||
for (int i = 1; i <= 5; i++) {
|
||||
//TIP 按 <shortcut actionId="Debug"/> 开始调试代码。我们已经设置了一个 <icon src="AllIcons.Debugger.Db_set_breakpoint"/> 断点
|
||||
// 但您始终可以通过按 <shortcut actionId="ToggleLineBreakpoint"/> 添加更多断点。
|
||||
System.out.println("i = " + i);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
server:
|
||||
port: 8080
|
||||
|
||||
spring:
|
||||
application:
|
||||
name: device-activation-platform
|
||||
Reference in New Issue
Block a user