package com.usky.vpp.crypto; import cn.hutool.core.codec.Base64; import cn.hutool.crypto.SmUtil; import cn.hutool.crypto.asymmetric.KeyType; import cn.hutool.crypto.asymmetric.SM2; import com.usky.vpp.config.VppUnProperties; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.util.StringUtils; import java.nio.charset.StandardCharsets; /** * 运管平台 UN/DN 国密加解密与签名(SM2/SM3withSM2) */ @Service public class VppUnCryptoService { private static final Logger log = LoggerFactory.getLogger(VppUnCryptoService.class); @Autowired private VppUnProperties properties; public boolean isActive() { return Boolean.TRUE.equals(properties.getCryptoEnabled()) && StringUtils.hasText(properties.getUnPublicKey()) && StringUtils.hasText(properties.getDnPrivateKey()); } public String encryptRequest(String plainJson) { SM2 sm2 = SmUtil.sm2(null, properties.getUnPublicKey()); return sm2.encryptBase64(plainJson, KeyType.PublicKey); } public String signRequest(String cipherBase64) { SM2 sm2 = SmUtil.sm2(properties.getDnPrivateKey(), null); byte[] sign = sm2.sign(cipherBase64.getBytes(StandardCharsets.UTF_8)); return Base64.encode(sign); } public String decryptResponse(String cipherBase64) { SM2 sm2 = SmUtil.sm2(properties.getDnPrivateKey(), properties.getDnPublicKey()); return sm2.decryptStr(cipherBase64, KeyType.PrivateKey); } public boolean verifyResponse(String cipherBase64, String signBase64) { return verifyInbound(cipherBase64, signBase64); } /** UN→DN 请求验签 */ public boolean verifyInbound(String cipherBase64, String signBase64) { if (!StringUtils.hasText(signBase64)) { log.warn("UN 请求缺少 X-Sign,跳过验签"); return true; } SM2 sm2 = SmUtil.sm2(null, properties.getUnPublicKey()); return sm2.verify(cipherBase64.getBytes(StandardCharsets.UTF_8), Base64.decode(signBase64)); } /** UN→DN 请求解密 */ public String decryptInbound(String cipherBase64) { return decryptResponse(cipherBase64); } /** DN→UN 响应加密 */ public String encryptOutbound(String plainJson) { return encryptRequest(plainJson); } /** DN→UN 响应签名 */ public String signOutbound(String cipherBase64) { return signRequest(cipherBase64); } }