From e88f6b43ad056c0a72ff1309bcaec1cdf83f7269 Mon Sep 17 00:00:00 2001 From: wh Date: Sun, 10 May 2026 22:04:52 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=9B=BD=E5=AF=86sm4?= =?UTF-8?q?=E5=8A=A0=E8=A7=A3=E5=AF=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 7 +- .../com/labelsys/backend/util/SM4Util.java | 104 ++++++++++++++++++ 2 files changed, 110 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/labelsys/backend/util/SM4Util.java diff --git a/pom.xml b/pom.xml index ad3696d..e02f2c1 100644 --- a/pom.xml +++ b/pom.xml @@ -84,6 +84,11 @@ lombok true + + org.bouncycastle + bcprov-jdk18on + 1.78.1 + software.amazon.awssdk s3 @@ -137,4 +142,4 @@ - + \ No newline at end of file diff --git a/src/main/java/com/labelsys/backend/util/SM4Util.java b/src/main/java/com/labelsys/backend/util/SM4Util.java new file mode 100644 index 0000000..1c6d144 --- /dev/null +++ b/src/main/java/com/labelsys/backend/util/SM4Util.java @@ -0,0 +1,104 @@ +package com.labelsys.backend.util; + +import org.bouncycastle.crypto.engines.SM4Engine; +import org.bouncycastle.crypto.modes.CBCBlockCipher; +import org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher; +import org.bouncycastle.crypto.params.KeyParameter; +import org.bouncycastle.crypto.params.ParametersWithIV; + +import java.nio.charset.StandardCharsets; +import java.util.Base64; + +public class SM4Util { + + private static final int KEY_LENGTH = 16; + private static final int IV_LENGTH = 16; + + public static String encrypt(String plainText, String key, String iv) { + try { + validateKey(key); + validateIV(iv); + + byte[] keyBytes = key.getBytes(StandardCharsets.UTF_8); + byte[] ivBytes = iv.getBytes(StandardCharsets.UTF_8); + byte[] plainBytes = plainText.getBytes(StandardCharsets.UTF_8); + + SM4Engine engine = new SM4Engine(); + CBCBlockCipher blockCipher = new CBCBlockCipher(engine); + PaddedBufferedBlockCipher cipher = new PaddedBufferedBlockCipher(blockCipher); + + KeyParameter keyParameter = new KeyParameter(keyBytes); + ParametersWithIV parametersWithIV = new ParametersWithIV(keyParameter, ivBytes); + cipher.init(true, parametersWithIV); + + byte[] encrypted = new byte[cipher.getOutputSize(plainBytes.length)]; + int len = cipher.processBytes(plainBytes, 0, plainBytes.length, encrypted, 0); + len += cipher.doFinal(encrypted, len); + + return Base64.getEncoder().encodeToString(encrypted); + } catch (Exception e) { + throw new RuntimeException("SM4加密失败", e); + } + } + + public static String decrypt(String cipherText, String key, String iv) { + try { + validateKey(key); + validateIV(iv); + + byte[] keyBytes = key.getBytes(StandardCharsets.UTF_8); + byte[] ivBytes = iv.getBytes(StandardCharsets.UTF_8); + byte[] cipherBytes = Base64.getDecoder().decode(cipherText); + + SM4Engine engine = new SM4Engine(); + CBCBlockCipher blockCipher = new CBCBlockCipher(engine); + PaddedBufferedBlockCipher cipher = new PaddedBufferedBlockCipher(blockCipher); + + KeyParameter keyParameter = new KeyParameter(keyBytes); + ParametersWithIV parametersWithIV = new ParametersWithIV(keyParameter, ivBytes); + cipher.init(false, parametersWithIV); + + byte[] decrypted = new byte[cipher.getOutputSize(cipherBytes.length)]; + int len = cipher.processBytes(cipherBytes, 0, cipherBytes.length, decrypted, 0); + len += cipher.doFinal(decrypted, len); + + return new String(decrypted, 0, len, StandardCharsets.UTF_8); + } catch (Exception e) { + throw new RuntimeException("SM4解密失败", e); + } + } + + public static String encrypt(String plainText, String key) { + return encrypt(plainText, key, key.substring(0, IV_LENGTH)); + } + + public static String decrypt(String cipherText, String key) { + return decrypt(cipherText, key, key.substring(0, IV_LENGTH)); + } + + private static void validateKey(String key) { + if (key == null || key.length() != KEY_LENGTH) { + throw new IllegalArgumentException("SM4密钥长度必须为16位"); + } + } + + private static void validateIV(String iv) { + if (iv == null || iv.length() != IV_LENGTH) { + throw new IllegalArgumentException("SM4 IV长度必须为16位"); + } + } + + static void main() { + String key = "1234567890123456"; + String iv = "abcdefghijklmnop"; + + String plainText = "Hello World!"; + + String encrypted = SM4Util.encrypt(plainText, key, iv); + String decrypted = SM4Util.decrypt(encrypted, key, iv); + + System.out.println("原文: " + plainText); + System.out.println("密文: " + encrypted); + System.out.println("解密: " + decrypted); + } +} \ No newline at end of file