|
@@ -0,0 +1,66 @@
|
|
|
+package org.eco.als.core;
|
|
|
+
|
|
|
+
|
|
|
+import org.eco.als.exception.LicenseException;
|
|
|
+import org.springframework.core.io.ClassPathResource;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
+
|
|
|
+import java.io.InputStream;
|
|
|
+import java.nio.file.Files;
|
|
|
+import java.nio.file.Paths;
|
|
|
+import java.security.KeyFactory;
|
|
|
+import java.security.PublicKey;
|
|
|
+import java.security.Signature;
|
|
|
+import java.security.spec.X509EncodedKeySpec;
|
|
|
+import java.time.LocalDate;
|
|
|
+import java.util.Base64;
|
|
|
+import java.util.Properties;
|
|
|
+
|
|
|
+/**
|
|
|
+ * @author GaoKunW
|
|
|
+ * @description LicenseValidator
|
|
|
+ * @date 2025/3/25 16:36
|
|
|
+ */
|
|
|
+@Service
|
|
|
+public class LicenseValidator {
|
|
|
+ public static void validate() throws Exception {
|
|
|
+ Properties props = new Properties();
|
|
|
+ try (InputStream is = Files.newInputStream(Paths.get("license.lic"))) {
|
|
|
+ props.load(is);
|
|
|
+ }
|
|
|
+
|
|
|
+ String licenseMac = props.getProperty("mac");
|
|
|
+ String licenseHost = props.getProperty("host");
|
|
|
+ String expiryDate = props.getProperty("expiry");
|
|
|
+ String signature = props.getProperty("signature");
|
|
|
+
|
|
|
+ // 验证系统信息
|
|
|
+ if (!licenseMac.equals(SystemInfo.getMacAddress()) ||
|
|
|
+ !licenseHost.equals(SystemInfo.getHostName())) {
|
|
|
+ throw new LicenseException("License does not match current system");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 验证过期时间
|
|
|
+ if (LocalDate.now().isAfter(LocalDate.parse(expiryDate))) {
|
|
|
+ throw new LicenseException("License has expired");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 验证签名
|
|
|
+ PublicKey publicKey = readPublicKey();
|
|
|
+ Signature sig = Signature.getInstance("SHA256withRSA");
|
|
|
+ sig.initVerify(publicKey);
|
|
|
+ sig.update((licenseMac + licenseHost + expiryDate).getBytes());
|
|
|
+
|
|
|
+ if (!sig.verify(Base64.getDecoder().decode(signature))) {
|
|
|
+ throw new LicenseException("Invalid license signature");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private static PublicKey readPublicKey() throws Exception {
|
|
|
+ try (InputStream is = new ClassPathResource("publicKey.der").getInputStream()) {
|
|
|
+ byte[] keyBytes = is.readAllBytes();
|
|
|
+ X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes);
|
|
|
+ return KeyFactory.getInstance("RSA").generatePublic(spec);
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|