1、完善推送kafka 的消息进行SM4加密
2、新增探针侧进行IP联动封禁的功能
This commit is contained in:
@@ -0,0 +1,55 @@
|
|||||||
|
package com.Modules;
|
||||||
|
|
||||||
|
import java.sql.*;
|
||||||
|
|
||||||
|
public class DMTDMTest {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
// 连接信息
|
||||||
|
String url = "jdbc:postgresql://139.9.39.176:16502/dameng";
|
||||||
|
String user = "SYSDBA";
|
||||||
|
String password = "Sysdba12345"; // 如果已修改密码,请替换为实际密码
|
||||||
|
|
||||||
|
Connection conn = null;
|
||||||
|
Statement stmt = null;
|
||||||
|
ResultSet rs = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 1. 加载驱动(JDBC 4.0 后自动加载,但显式加载更稳妥)
|
||||||
|
Class.forName("dm.jdbc.driver.DmDriver");
|
||||||
|
System.out.println("达梦 JDBC 驱动加载成功");
|
||||||
|
|
||||||
|
// 2. 建立连接
|
||||||
|
conn = DriverManager.getConnection(url, user, password);
|
||||||
|
System.out.println("数据库连接成功!");
|
||||||
|
|
||||||
|
// 3. 执行查询(达梦支持 DUAL 表)
|
||||||
|
stmt = conn.createStatement();
|
||||||
|
rs = stmt.executeQuery("SELECT 1 FROM DUAL");
|
||||||
|
|
||||||
|
if (rs.next()) {
|
||||||
|
int result = rs.getInt(1);
|
||||||
|
System.out.println("查询结果: " + result);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. 可选:查询当前时间
|
||||||
|
rs.close();
|
||||||
|
rs = stmt.executeQuery("SELECT SYSDATE FROM DUAL");
|
||||||
|
if (rs.next()) {
|
||||||
|
Timestamp now = rs.getTimestamp(1);
|
||||||
|
System.out.println("服务器当前时间: " + now);
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (ClassNotFoundException e) {
|
||||||
|
System.err.println("未找到达梦 JDBC 驱动,请检查 DmJdbcDriver18.jar 是否在 classpath 中");
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
System.err.println("数据库连接或操作失败");
|
||||||
|
e.printStackTrace();
|
||||||
|
} finally {
|
||||||
|
// 5. 关闭资源
|
||||||
|
try { if (rs != null) rs.close(); } catch (SQLException e) { e.printStackTrace(); }
|
||||||
|
try { if (stmt != null) stmt.close(); } catch (SQLException e) { e.printStackTrace(); }
|
||||||
|
try { if (conn != null) conn.close(); } catch (SQLException e) { e.printStackTrace(); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,137 @@
|
|||||||
|
package com.common.util;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.HexUtil;
|
||||||
|
import cn.hutool.crypto.Mode;
|
||||||
|
import cn.hutool.crypto.Padding;
|
||||||
|
import cn.hutool.crypto.SmUtil;
|
||||||
|
import cn.hutool.crypto.symmetric.SM4;
|
||||||
|
import cn.hutool.crypto.symmetric.SymmetricCrypto;
|
||||||
|
import javax.crypto.spec.IvParameterSpec;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.security.Security;
|
||||||
|
import java.util.Base64;
|
||||||
|
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.HexUtil;
|
||||||
|
import cn.hutool.core.util.RandomUtil;
|
||||||
|
import javax.crypto.SecretKey;
|
||||||
|
import javax.crypto.spec.SecretKeySpec;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 国密SM4加解密工具类
|
||||||
|
* 基于 Hutool + Bouncy Castle 实现,支持 ECB 和 CBC 模式
|
||||||
|
*/
|
||||||
|
public class Sm4Util {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成 SM4 密钥(16字节,128位)
|
||||||
|
* @return 十六进制字符串格式的密钥
|
||||||
|
*/
|
||||||
|
public static String generateKey() {
|
||||||
|
byte[] key = SmUtil.sm4().getSecretKey().getEncoded();
|
||||||
|
return HexUtil.encodeHexStr(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==================== ECB 模式(电子密码本模式) ====================
|
||||||
|
// 注意:ECB 模式不需要 IV,但安全性较低,不适合加密大量数据
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 使用 ECB 模式加密
|
||||||
|
* @param plainText 明文
|
||||||
|
* @param hexKey 十六进制字符串格式的密钥
|
||||||
|
* @return Base64 编码的密文
|
||||||
|
*/
|
||||||
|
public static String encryptEcb(String plainText, String hexKey) {
|
||||||
|
SM4 sm4 = new SM4(HexUtil.decodeHex(hexKey));
|
||||||
|
return sm4.encryptBase64(plainText);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 使用 ECB 模式解密
|
||||||
|
* @param cipherText Base64 编码的密文
|
||||||
|
* @param hexKey 十六进制字符串格式的密钥
|
||||||
|
* @return 明文
|
||||||
|
*/
|
||||||
|
public static String decryptEcb(String cipherText, String hexKey) {
|
||||||
|
SM4 sm4 = new SM4(HexUtil.decodeHex(hexKey));
|
||||||
|
return sm4.decryptStr(cipherText);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==================== CBC 模式(密码分组链接模式) ====================
|
||||||
|
// 推荐使用:需要 IV(初始化向量),安全性更高
|
||||||
|
|
||||||
|
|
||||||
|
static {
|
||||||
|
// 静态代码块中统一注册 Provider,确保全局生效
|
||||||
|
if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null) {
|
||||||
|
Security.addProvider(new BouncyCastleProvider());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CBC 模式加密(推荐)
|
||||||
|
* @param plainText 明文
|
||||||
|
* @param hexKey 十六进制字符串格式的密钥
|
||||||
|
* @return 格式为 "Base64(IV):Base64(密文)" 的字符串
|
||||||
|
*/
|
||||||
|
public static String encryptCbc(String plainText, String hexKey) {
|
||||||
|
// 1. 随机生成16字节 IV
|
||||||
|
byte[] iv = RandomUtil.randomBytes(16);
|
||||||
|
// 2. 将 IV 包装为 AlgorithmParameterSpec
|
||||||
|
IvParameterSpec ivSpec = new IvParameterSpec(iv);
|
||||||
|
// 3. 将十六进制密钥转为字节数组并包装为 SecretKey
|
||||||
|
byte[] keyBytes = HexUtil.decodeHex(hexKey);
|
||||||
|
SecretKey secretKey = new SecretKeySpec(keyBytes, "SM4");
|
||||||
|
// 4. 创建加解密器
|
||||||
|
SymmetricCrypto sm4 = new SymmetricCrypto("SM4/CBC/PKCS5Padding", secretKey, ivSpec);
|
||||||
|
// 5. 执行加密
|
||||||
|
String encryptedBase64 = sm4.encryptBase64(plainText);
|
||||||
|
String ivBase64 = Base64.getEncoder().encodeToString(iv);
|
||||||
|
return ivBase64 + ":" + encryptedBase64;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CBC 模式解密
|
||||||
|
* @param cipherTextWithIv 由 encryptCbc 生成的字符串
|
||||||
|
* @param hexKey 十六进制密钥
|
||||||
|
* @return 明文
|
||||||
|
*/
|
||||||
|
public static String decryptCbc(String cipherTextWithIv, String hexKey) {
|
||||||
|
String[] parts = cipherTextWithIv.split(":");
|
||||||
|
if (parts.length != 2) {
|
||||||
|
throw new IllegalArgumentException("无效的密文格式,应为 'IV:密文'");
|
||||||
|
}
|
||||||
|
// 1. 解析 IV
|
||||||
|
byte[] iv = Base64.getDecoder().decode(parts[0]);
|
||||||
|
IvParameterSpec ivSpec = new IvParameterSpec(iv);
|
||||||
|
// 2. 解析密钥
|
||||||
|
byte[] keyBytes = HexUtil.decodeHex(hexKey);
|
||||||
|
SecretKey secretKey = new SecretKeySpec(keyBytes, "SM4");
|
||||||
|
// 3. 创建解密器(算法参数必须与加密时完全一致)
|
||||||
|
SymmetricCrypto sm4 = new SymmetricCrypto("SM4/CBC/PKCS5Padding", secretKey, ivSpec);
|
||||||
|
// 4. 解密
|
||||||
|
return sm4.decryptStr(parts[1]);
|
||||||
|
}
|
||||||
|
public static void main(String[] args) {
|
||||||
|
// 1. 生成 SM4 密钥(128位,十六进制字符串)
|
||||||
|
String hexKey = Sm4Util.generateKey();
|
||||||
|
System.out.println("生成的密钥(十六进制): " + hexKey);
|
||||||
|
System.out.println("密钥长度: " + HexUtil.decodeHex(hexKey).length + " 字节");
|
||||||
|
|
||||||
|
// 2. 原始明文(包含中文和英文,测试字符集兼容性)
|
||||||
|
String plainText = "Hello 国密算法!SM4 加解密测试。123456";
|
||||||
|
System.out.println("原始明文: " + plainText);
|
||||||
|
|
||||||
|
// 3. 使用 CBC 模式加密
|
||||||
|
String encryptedWithIv = Sm4Util.encryptCbc(plainText, hexKey);
|
||||||
|
System.out.println("加密结果(IV:密文): " + encryptedWithIv);
|
||||||
|
|
||||||
|
// 4. 使用 CBC 模式解密
|
||||||
|
String decryptedText = Sm4Util.decryptCbc(encryptedWithIv, hexKey);
|
||||||
|
System.out.println("解密后的明文: " + decryptedText);
|
||||||
|
|
||||||
|
// 5. 验证加解密是否一致
|
||||||
|
boolean success = plainText.equals(decryptedText);
|
||||||
|
System.out.println("加解密验证结果: " + (success ? "成功" : " 失败"));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -11,10 +11,13 @@ import com.netty.SyslogServer;
|
|||||||
import com.haobang.config.AppConfig;
|
import com.haobang.config.AppConfig;
|
||||||
import org.springframework.cache.annotation.EnableCaching;
|
import org.springframework.cache.annotation.EnableCaching;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||||
import com.netty.SyslogServerBoth;
|
import com.netty.SyslogServerBoth;
|
||||||
|
|
||||||
|
|
||||||
@MapperScan("com.common.mapper")
|
@MapperScan("com.common.mapper")
|
||||||
@SpringBootApplication
|
@SpringBootApplication
|
||||||
|
@EnableScheduling
|
||||||
public class SyslogServeMainApp {
|
public class SyslogServeMainApp {
|
||||||
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(SyslogServeMainApp.class);
|
private static final Logger logger = LoggerFactory.getLogger(SyslogServeMainApp.class);
|
||||||
|
|||||||
+22
@@ -0,0 +1,22 @@
|
|||||||
|
package com.common.controller;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import com.common.entity.BlockResponse;
|
||||||
|
import com.common.service.BlacklistApiService;
|
||||||
|
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/api/blacklist")
|
||||||
|
public class BlacklistController {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private BlacklistApiService blacklistApiService;
|
||||||
|
|
||||||
|
@PostMapping("/add")
|
||||||
|
public BlockResponse addIp(@RequestParam String ip,
|
||||||
|
@RequestParam(defaultValue = "300") String age,
|
||||||
|
@RequestParam(defaultValue = "1") String enable) {
|
||||||
|
return blacklistApiService.addToBlacklist(ip, age, enable);
|
||||||
|
}
|
||||||
|
}
|
||||||
+18
@@ -0,0 +1,18 @@
|
|||||||
|
package com.common.entity;
|
||||||
|
|
||||||
|
public class BlacklistApiProperties {
|
||||||
|
private final String url;
|
||||||
|
private final String username;
|
||||||
|
private final String password;
|
||||||
|
|
||||||
|
public BlacklistApiProperties(String url, String username, String password) {
|
||||||
|
this.url = url;
|
||||||
|
this.username = username;
|
||||||
|
this.password = password;
|
||||||
|
}
|
||||||
|
|
||||||
|
// getters
|
||||||
|
public String getUrl() { return url; }
|
||||||
|
public String getUsername() { return username; }
|
||||||
|
public String getPassword() { return password; }
|
||||||
|
}
|
||||||
+22
@@ -0,0 +1,22 @@
|
|||||||
|
package com.common.entity;
|
||||||
|
|
||||||
|
public class BlacklistRequest {
|
||||||
|
private String blist;
|
||||||
|
private String age;
|
||||||
|
private String enable;
|
||||||
|
|
||||||
|
// 构造器、getter/setter
|
||||||
|
public BlacklistRequest() {}
|
||||||
|
public BlacklistRequest(String blist, String age, String enable) {
|
||||||
|
this.blist = blist;
|
||||||
|
this.age = age;
|
||||||
|
this.enable = enable;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getBlist() { return blist; }
|
||||||
|
public void setBlist(String blist) { this.blist = blist; }
|
||||||
|
public String getAge() { return age; }
|
||||||
|
public void setAge(String age) { this.age = age; }
|
||||||
|
public String getEnable() { return enable; }
|
||||||
|
public void setEnable(String enable) { this.enable = enable; }
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package com.common.entity;
|
||||||
|
import lombok.Data;
|
||||||
|
import javax.validation.constraints.NotBlank;
|
||||||
|
import javax.validation.constraints.Pattern;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonTypeInfo;
|
||||||
|
@Data
|
||||||
|
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||||
|
@JsonTypeInfo(use = JsonTypeInfo.Id.NONE) // 强制禁用类型标识
|
||||||
|
public class BlockRequest {
|
||||||
|
@NotBlank(message = "IP不能为空")
|
||||||
|
@Pattern(regexp = "^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$",
|
||||||
|
message = "无效的IPv4地址")
|
||||||
|
private String ip;
|
||||||
|
|
||||||
|
private String reason; // 可选:封堵原因
|
||||||
|
|
||||||
|
// getters & setters
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
package com.common.entity;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
@Data
|
||||||
|
public class BlockResponse {
|
||||||
|
|
||||||
|
|
||||||
|
private int code;
|
||||||
|
private String message;
|
||||||
|
private Object data;
|
||||||
|
|
||||||
|
|
||||||
|
// 全参构造器
|
||||||
|
public BlockResponse(int code, String message, Object data) {
|
||||||
|
this.code = code;
|
||||||
|
this.message = message;
|
||||||
|
this.data = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 构造器、getters & setters
|
||||||
|
}
|
||||||
+46
@@ -0,0 +1,46 @@
|
|||||||
|
package com.common.service;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.http.*;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.web.client.RestTemplate;
|
||||||
|
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.Base64;
|
||||||
|
import com.common.entity.BlacklistApiProperties;
|
||||||
|
import com.common.entity.BlacklistRequest;
|
||||||
|
import com.common.entity.BlockResponse;
|
||||||
|
@Service
|
||||||
|
public class BlacklistApiService {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private RestTemplate restTemplate;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private BlacklistApiProperties apiProperties;
|
||||||
|
|
||||||
|
public BlockResponse addToBlacklist(String ip, String age, String enable) {
|
||||||
|
String url = apiProperties.getUrl();
|
||||||
|
|
||||||
|
// 构建请求体
|
||||||
|
BlacklistRequest requestBody = new BlacklistRequest(ip, age, enable);
|
||||||
|
|
||||||
|
// 设置请求头
|
||||||
|
HttpHeaders headers = new HttpHeaders();
|
||||||
|
headers.setContentType(MediaType.APPLICATION_JSON);
|
||||||
|
|
||||||
|
// Basic Auth 编码(密码含特殊字符 % 无需额外处理,Base64 直接编码字节)
|
||||||
|
String auth = apiProperties.getUsername() + ":" + apiProperties.getPassword();
|
||||||
|
byte[] encodedAuth = Base64.getEncoder().encode(auth.getBytes(StandardCharsets.ISO_8859_1));
|
||||||
|
String authHeader = "Basic " + new String(encodedAuth, StandardCharsets.ISO_8859_1);
|
||||||
|
headers.set("Authorization", authHeader);
|
||||||
|
|
||||||
|
HttpEntity<BlacklistRequest> entity = new HttpEntity<>(requestBody, headers);
|
||||||
|
|
||||||
|
// 发送 POST 请求
|
||||||
|
ResponseEntity<BlockResponse> response = restTemplate.exchange(
|
||||||
|
url, HttpMethod.POST, entity, BlockResponse.class);
|
||||||
|
|
||||||
|
return response.getBody();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
package com.config;
|
||||||
|
|
||||||
|
import org.apache.http.conn.ssl.NoopHostnameVerifier;
|
||||||
|
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
|
||||||
|
import org.apache.http.impl.client.CloseableHttpClient;
|
||||||
|
import org.apache.http.impl.client.HttpClients;
|
||||||
|
import org.apache.http.ssl.SSLContextBuilder;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
|
||||||
|
import org.springframework.web.client.RestTemplate;
|
||||||
|
import com.common.entity.BlacklistApiProperties;
|
||||||
|
import javax.net.ssl.SSLContext;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
public class RestTemplateConfig {
|
||||||
|
|
||||||
|
@Value("${blacklist.api.url}")
|
||||||
|
private String apiUrl;
|
||||||
|
|
||||||
|
@Value("${blacklist.api.username}")
|
||||||
|
private String username;
|
||||||
|
|
||||||
|
@Value("${blacklist.api.password}")
|
||||||
|
private String password;
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public RestTemplate restTemplate() throws Exception {
|
||||||
|
// 忽略 SSL 证书验证(仅用于内网/测试环境,生产环境建议使用真实证书)
|
||||||
|
SSLContext sslContext = SSLContextBuilder.create()
|
||||||
|
.loadTrustMaterial((chain, authType) -> true)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(
|
||||||
|
sslContext, NoopHostnameVerifier.INSTANCE);
|
||||||
|
|
||||||
|
CloseableHttpClient httpClient = HttpClients.custom()
|
||||||
|
.setSSLSocketFactory(socketFactory)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(httpClient);
|
||||||
|
return new RestTemplate(factory);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public BlacklistApiProperties blacklistApiProperties() {
|
||||||
|
return new BlacklistApiProperties(apiUrl, username, password);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -128,5 +128,8 @@ public class AppConfig {
|
|||||||
return config.getInt("app.service.device_collect_id");
|
return config.getInt("app.service.device_collect_id");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String getSM4Key() {
|
||||||
|
return config.getString("syslog.sm4.generateKey");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,137 @@
|
|||||||
|
package com.haobang.util;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.HexUtil;
|
||||||
|
import cn.hutool.crypto.Mode;
|
||||||
|
import cn.hutool.crypto.Padding;
|
||||||
|
import cn.hutool.crypto.SmUtil;
|
||||||
|
import cn.hutool.crypto.symmetric.SM4;
|
||||||
|
import cn.hutool.crypto.symmetric.SymmetricCrypto;
|
||||||
|
import javax.crypto.spec.IvParameterSpec;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.security.Security;
|
||||||
|
import java.util.Base64;
|
||||||
|
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.HexUtil;
|
||||||
|
import cn.hutool.core.util.RandomUtil;
|
||||||
|
import javax.crypto.SecretKey;
|
||||||
|
import javax.crypto.spec.SecretKeySpec;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 国密SM4加解密工具类
|
||||||
|
* 基于 Hutool + Bouncy Castle 实现,支持 ECB 和 CBC 模式
|
||||||
|
*/
|
||||||
|
public class Sm4Util {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成 SM4 密钥(16字节,128位)
|
||||||
|
* @return 十六进制字符串格式的密钥
|
||||||
|
*/
|
||||||
|
public static String generateKey() {
|
||||||
|
byte[] key = SmUtil.sm4().getSecretKey().getEncoded();
|
||||||
|
return HexUtil.encodeHexStr(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==================== ECB 模式(电子密码本模式) ====================
|
||||||
|
// 注意:ECB 模式不需要 IV,但安全性较低,不适合加密大量数据
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 使用 ECB 模式加密
|
||||||
|
* @param plainText 明文
|
||||||
|
* @param hexKey 十六进制字符串格式的密钥
|
||||||
|
* @return Base64 编码的密文
|
||||||
|
*/
|
||||||
|
public static String encryptEcb(String plainText, String hexKey) {
|
||||||
|
SM4 sm4 = new SM4(HexUtil.decodeHex(hexKey));
|
||||||
|
return sm4.encryptBase64(plainText);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 使用 ECB 模式解密
|
||||||
|
* @param cipherText Base64 编码的密文
|
||||||
|
* @param hexKey 十六进制字符串格式的密钥
|
||||||
|
* @return 明文
|
||||||
|
*/
|
||||||
|
public static String decryptEcb(String cipherText, String hexKey) {
|
||||||
|
SM4 sm4 = new SM4(HexUtil.decodeHex(hexKey));
|
||||||
|
return sm4.decryptStr(cipherText);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==================== CBC 模式(密码分组链接模式) ====================
|
||||||
|
// 推荐使用:需要 IV(初始化向量),安全性更高
|
||||||
|
|
||||||
|
|
||||||
|
static {
|
||||||
|
// 静态代码块中统一注册 Provider,确保全局生效
|
||||||
|
if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null) {
|
||||||
|
Security.addProvider(new BouncyCastleProvider());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CBC 模式加密(推荐)
|
||||||
|
* @param plainText 明文
|
||||||
|
* @param hexKey 十六进制字符串格式的密钥
|
||||||
|
* @return 格式为 "Base64(IV):Base64(密文)" 的字符串
|
||||||
|
*/
|
||||||
|
public static String encryptCbc(String plainText, String hexKey) {
|
||||||
|
// 1. 随机生成16字节 IV
|
||||||
|
byte[] iv = RandomUtil.randomBytes(16);
|
||||||
|
// 2. 将 IV 包装为 AlgorithmParameterSpec
|
||||||
|
IvParameterSpec ivSpec = new IvParameterSpec(iv);
|
||||||
|
// 3. 将十六进制密钥转为字节数组并包装为 SecretKey
|
||||||
|
byte[] keyBytes = HexUtil.decodeHex(hexKey);
|
||||||
|
SecretKey secretKey = new SecretKeySpec(keyBytes, "SM4");
|
||||||
|
// 4. 创建加解密器
|
||||||
|
SymmetricCrypto sm4 = new SymmetricCrypto("SM4/CBC/PKCS5Padding", secretKey, ivSpec);
|
||||||
|
// 5. 执行加密
|
||||||
|
String encryptedBase64 = sm4.encryptBase64(plainText);
|
||||||
|
String ivBase64 = Base64.getEncoder().encodeToString(iv);
|
||||||
|
return ivBase64 + ":" + encryptedBase64;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CBC 模式解密
|
||||||
|
* @param cipherTextWithIv 由 encryptCbc 生成的字符串
|
||||||
|
* @param hexKey 十六进制密钥
|
||||||
|
* @return 明文
|
||||||
|
*/
|
||||||
|
public static String decryptCbc(String cipherTextWithIv, String hexKey) {
|
||||||
|
String[] parts = cipherTextWithIv.split(":");
|
||||||
|
if (parts.length != 2) {
|
||||||
|
throw new IllegalArgumentException("无效的密文格式,应为 'IV:密文'");
|
||||||
|
}
|
||||||
|
// 1. 解析 IV
|
||||||
|
byte[] iv = Base64.getDecoder().decode(parts[0]);
|
||||||
|
IvParameterSpec ivSpec = new IvParameterSpec(iv);
|
||||||
|
// 2. 解析密钥
|
||||||
|
byte[] keyBytes = HexUtil.decodeHex(hexKey);
|
||||||
|
SecretKey secretKey = new SecretKeySpec(keyBytes, "SM4");
|
||||||
|
// 3. 创建解密器(算法参数必须与加密时完全一致)
|
||||||
|
SymmetricCrypto sm4 = new SymmetricCrypto("SM4/CBC/PKCS5Padding", secretKey, ivSpec);
|
||||||
|
// 4. 解密
|
||||||
|
return sm4.decryptStr(parts[1]);
|
||||||
|
}
|
||||||
|
public static void main(String[] args) {
|
||||||
|
// 1. 生成 SM4 密钥(128位,十六进制字符串)
|
||||||
|
String hexKey = Sm4Util.generateKey();
|
||||||
|
System.out.println("生成的密钥(十六进制): " + hexKey);
|
||||||
|
System.out.println("密钥长度: " + HexUtil.decodeHex(hexKey).length + " 字节");
|
||||||
|
|
||||||
|
// 2. 原始明文(包含中文和英文,测试字符集兼容性)
|
||||||
|
String plainText = "Hello 国密算法!SM4 加解密测试。123456";
|
||||||
|
System.out.println("原始明文: " + plainText);
|
||||||
|
|
||||||
|
// 3. 使用 CBC 模式加密
|
||||||
|
String encryptedWithIv = Sm4Util.encryptCbc(plainText, hexKey);
|
||||||
|
System.out.println("加密结果(IV:密文): " + encryptedWithIv);
|
||||||
|
|
||||||
|
// 4. 使用 CBC 模式解密
|
||||||
|
String decryptedText = Sm4Util.decryptCbc(encryptedWithIv, hexKey);
|
||||||
|
System.out.println("解密后的明文: " + decryptedText);
|
||||||
|
|
||||||
|
// 5. 验证加解密是否一致
|
||||||
|
boolean success = plainText.equals(decryptedText);
|
||||||
|
System.out.println("加解密验证结果: " + (success ? "成功" : " 失败"));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.kafka;
|
package com.kafka;
|
||||||
import com.common.entity.DeviceDevice;
|
import com.common.entity.DeviceDevice;
|
||||||
|
import com.haobang.util.Sm4Util;
|
||||||
import org.apache.kafka.clients.producer.*;
|
import org.apache.kafka.clients.producer.*;
|
||||||
import org.apache.kafka.common.serialization.StringSerializer;
|
import org.apache.kafka.common.serialization.StringSerializer;
|
||||||
|
|
||||||
@@ -17,7 +18,7 @@ import com.haobang.util.DeviceInfoUtil;
|
|||||||
public class kafkaProducer {
|
public class kafkaProducer {
|
||||||
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(kafkaProducer.class);
|
private static final Logger logger = LoggerFactory.getLogger(kafkaProducer.class);
|
||||||
|
private static String strhexKey=AppConfig.getSM4Key();
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
// System.out.println(getFullLogString("syslogmessage"));
|
// System.out.println(getFullLogString("syslogmessage"));
|
||||||
|
|
||||||
@@ -100,9 +101,14 @@ public class kafkaProducer {
|
|||||||
//String value = DeviceInfoUtil.getFullLogString(strSyslog);
|
//String value = DeviceInfoUtil.getFullLogString(strSyslog);
|
||||||
//采用动态获取Syslog 请求的设备信息
|
//采用动态获取Syslog 请求的设备信息
|
||||||
String value = DeviceInfoUtil.getFullLogString(deviceDevice,strSyslog,strReceiveTime);
|
String value = DeviceInfoUtil.getFullLogString(deviceDevice,strSyslog,strReceiveTime);
|
||||||
|
|
||||||
|
//Message进行SM4加密写入kafka
|
||||||
|
String Sm4message= Sm4Util.encryptCbc(value, strhexKey);
|
||||||
|
System.out.println("Sm4message:"+Sm4message);
|
||||||
|
|
||||||
// 创建生产者记录
|
// 创建生产者记录
|
||||||
ProducerRecord<String, String> record =
|
ProducerRecord<String, String> record =
|
||||||
new ProducerRecord<>(AppConfig.getKafkaProducerTopic(), key, value);
|
new ProducerRecord<>(AppConfig.getKafkaProducerTopic(), key, Sm4message);
|
||||||
|
|
||||||
// 发送消息(异步方式)
|
// 发送消息(异步方式)
|
||||||
producer.send(record, new Callback() {
|
producer.send(record, new Callback() {
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ import org.slf4j.LoggerFactory;
|
|||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import com.kafka.kafkaProducer;
|
import com.kafka.kafkaProducer;
|
||||||
import com.Modules.Device.DeviceProcess;
|
import com.Modules.Device.DeviceProcess;
|
||||||
|
import com.haobang.util.Sm4Util;
|
||||||
|
import com.haobang.config.AppConfig;
|
||||||
/**
|
/**
|
||||||
* Syslog 消息处理器
|
* Syslog 消息处理器
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ syslog.tcp.port=514
|
|||||||
syslog.udp.port=514
|
syslog.udp.port=514
|
||||||
syslog.max.frame.length=262144
|
syslog.max.frame.length=262144
|
||||||
syslog.buffer.size=1000
|
syslog.buffer.size=1000
|
||||||
|
syslog.sm4.generateKey=f79548ab6fa8a304fc0115e17230358a
|
||||||
|
|
||||||
# APP Service Configuration
|
# APP Service Configuration
|
||||||
app.service.device_id=1
|
app.service.device_id=1
|
||||||
@@ -55,3 +55,37 @@ spring.redis.lettuce.pool.min-idle=0
|
|||||||
spring.cache.redis.time-to-live=600000
|
spring.cache.redis.time-to-live=600000
|
||||||
|
|
||||||
|
|
||||||
|
#防火墙封堵配置
|
||||||
|
# 是否启用真实封堵(false时仅打印日志,用于测试)
|
||||||
|
firewall.enabled=true
|
||||||
|
# iptables命令路径(通常为 /usr/sbin/iptables)
|
||||||
|
firewall.iptables-path=/usr/sbin/iptables
|
||||||
|
# 封堵链(常用 INPUT 或 FORWARD)
|
||||||
|
firewall.chain=INPUT
|
||||||
|
# 封堵策略(DROP 或 REJECT)
|
||||||
|
firewall.target=DROP
|
||||||
|
# 可选:API访问密钥(若为空则不校验)
|
||||||
|
firewall.api-key=your-secure-api-key
|
||||||
|
|
||||||
|
|
||||||
|
# 黑名单API配置
|
||||||
|
blacklist.api.url= https://103.43.84.11/api/v3/Objects/Blacklist
|
||||||
|
blacklist.api.username=apt-admin103
|
||||||
|
blacklist.api.password=C9W2xYgfc%SN1
|
||||||
|
|
||||||
|
# 白名单API配置
|
||||||
|
whitelist.api.url=https://103.43.84.11/api/v3/Policies/GlobalWhitelist
|
||||||
|
whitelist.api.username=apt-admin103
|
||||||
|
whitelist.api.password=C9W2xYgfc%SN1
|
||||||
|
|
||||||
|
# ============================================
|
||||||
|
# 探针联动配置
|
||||||
|
# ============================================
|
||||||
|
# 是否启用联动功能
|
||||||
|
interlocking.enabled=true
|
||||||
|
# syslog-consumer API基础URL(安全平台外网映射地址)
|
||||||
|
interlocking.api.base-url=http://localhost:8089/xdrservice/interlocking
|
||||||
|
# API-KEY认证(32位,需与syslog-consumer配置一致)
|
||||||
|
interlocking.api-key=a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6
|
||||||
|
# 定时任务执行间隔(毫秒),默认30秒
|
||||||
|
interlocking.schedule.interval=30000
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ syslog.tcp.port=514
|
|||||||
syslog.udp.port=514
|
syslog.udp.port=514
|
||||||
syslog.max.frame.length=262144
|
syslog.max.frame.length=262144
|
||||||
syslog.buffer.size=1000
|
syslog.buffer.size=1000
|
||||||
|
syslog.sm4.generateKey=f79548ab6fa8a304fc0115e17230358a
|
||||||
# APP Service Configuration
|
# APP Service Configuration
|
||||||
app.service.device_id=1
|
app.service.device_id=1
|
||||||
app.service.device_name=honeypot
|
app.service.device_name=honeypot
|
||||||
@@ -52,4 +52,39 @@ spring.redis.lettuce.pool.max-idle=10
|
|||||||
spring.redis.lettuce.pool.min-idle=5
|
spring.redis.lettuce.pool.min-idle=5
|
||||||
|
|
||||||
# 生产环境缓存时间较长
|
# 生产环境缓存时间较长
|
||||||
spring.cache.redis.time-to-live=3600000
|
spring.cache.redis.time-to-live=3600000
|
||||||
|
|
||||||
|
#防火墙封堵配置
|
||||||
|
# 是否启用真实封堵(false时仅打印日志,用于测试)
|
||||||
|
firewall.enabled=true
|
||||||
|
# iptables命令路径(通常为 /usr/sbin/iptables)
|
||||||
|
firewall.iptables-path=/usr/sbin/iptables
|
||||||
|
# 封堵链(常用 INPUT 或 FORWARD)
|
||||||
|
firewall.chain=INPUT
|
||||||
|
# 封堵策略(DROP 或 REJECT)
|
||||||
|
firewall.target=DROP
|
||||||
|
# 可选:API访问密钥(若为空则不校验)
|
||||||
|
firewall.api-key=your-secure-api-key
|
||||||
|
|
||||||
|
|
||||||
|
# 黑名单API配置
|
||||||
|
blacklist.api.url= https://103.43.84.11/api/v3/Objects/Blacklist
|
||||||
|
blacklist.api.username=apt-admin103
|
||||||
|
blacklist.api.password=C9W2xYgfc%SN1
|
||||||
|
|
||||||
|
# 白名单API配置
|
||||||
|
whitelist.api.url=https://103.43.84.11/api/v3/Policies/GlobalWhitelist
|
||||||
|
whitelist.api.username=apt-admin103
|
||||||
|
whitelist.api.password=C9W2xYgfc%SN1
|
||||||
|
|
||||||
|
# ============================================
|
||||||
|
# 探针联动配置
|
||||||
|
# ============================================
|
||||||
|
# 是否启用联动功能
|
||||||
|
interlocking.enabled=true
|
||||||
|
# syslog-consumer API基础URL(安全平台外网映射地址)
|
||||||
|
interlocking.api.base-url=http://localhost:8089/xdrservice/interlocking
|
||||||
|
# API-KEY认证(32位,需与syslog-consumer配置一致)
|
||||||
|
interlocking.api-key=a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6
|
||||||
|
# 定时任务执行间隔(毫秒),默认30秒
|
||||||
|
interlocking.schedule.interval=30000
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ syslog.tcp.port=514
|
|||||||
syslog.udp.port=514
|
syslog.udp.port=514
|
||||||
syslog.max.frame.length=262144
|
syslog.max.frame.length=262144
|
||||||
syslog.buffer.size=1000
|
syslog.buffer.size=1000
|
||||||
|
syslog.sm4.generateKey=f79548ab6fa8a304fc0115e17230358a
|
||||||
|
|
||||||
# APP Service Configuration
|
# APP Service Configuration
|
||||||
app.service.device_id=1
|
app.service.device_id=1
|
||||||
@@ -55,3 +55,37 @@ spring.redis.lettuce.pool.min-idle=0
|
|||||||
spring.cache.redis.time-to-live=600000
|
spring.cache.redis.time-to-live=600000
|
||||||
|
|
||||||
|
|
||||||
|
#防火墙封堵配置
|
||||||
|
# 是否启用真实封堵(false时仅打印日志,用于测试)
|
||||||
|
firewall.enabled=true
|
||||||
|
# iptables命令路径(通常为 /usr/sbin/iptables)
|
||||||
|
firewall.iptables-path=/usr/sbin/iptables
|
||||||
|
# 封堵链(常用 INPUT 或 FORWARD)
|
||||||
|
firewall.chain=INPUT
|
||||||
|
# 封堵策略(DROP 或 REJECT)
|
||||||
|
firewall.target=DROP
|
||||||
|
# 可选:API访问密钥(若为空则不校验)
|
||||||
|
firewall.api-key=your-secure-api-key
|
||||||
|
|
||||||
|
|
||||||
|
# 黑名单API配置
|
||||||
|
blacklist.api.url= https://103.43.84.11/api/v3/Objects/Blacklist
|
||||||
|
blacklist.api.username=apt-admin103
|
||||||
|
blacklist.api.password=C9W2xYgfc%SN1
|
||||||
|
|
||||||
|
# 白名单API配置
|
||||||
|
whitelist.api.url=https://103.43.84.11/api/v3/Policies/GlobalWhitelist
|
||||||
|
whitelist.api.username=apt-admin103
|
||||||
|
whitelist.api.password=C9W2xYgfc%SN1
|
||||||
|
|
||||||
|
# ============================================
|
||||||
|
# 探针联动配置
|
||||||
|
# ============================================
|
||||||
|
# 是否启用联动功能
|
||||||
|
interlocking.enabled=true
|
||||||
|
# syslog-consumer API基础URL(安全平台外网映射地址)
|
||||||
|
interlocking.api.base-url=http://localhost:8089/xdrservice/interlocking
|
||||||
|
# API-KEY认证(32位,需与syslog-consumer配置一致)
|
||||||
|
interlocking.api-key=a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6
|
||||||
|
# 定时任务执行间隔(毫秒),默认30秒
|
||||||
|
interlocking.schedule.interval=30000
|
||||||
|
|||||||
Reference in New Issue
Block a user