Java Spring Boot中的SM2和SM4加密算法SM2Util

在互联网时代,数据加密和安全性问题变得尤为重要。为了保护数据的安全性,人们不断研究和开发各种加密算法。其中,SM2和SM4算法是中国国家密码管理局推出的一种密码算法标准,被广泛应用于电子商务、金融数据传输等领域。在Java Spring Boot项目中,我们可以利用SM2Util工具类来实现SM2和SM4的加密功能。

SM2和SM4加密算法

SM2算法

SM2算法是由中国密码技术专家联合提出的一种基于椭圆曲线密码体系(ECC)的公钥密码算法。它具有高强度、高安全性、高效率和免费开放等特点,被广泛应用于数字证书、加密通信等领域。

SM4算法

SM4算法是一种分组密码算法,也被称为SMS4算法,它是中国国家密码管理局推出的一种分组密码算法标准。SM4算法具有较高的安全性和效率,适用于数据加密、文件加密等场景。

Java Spring Boot中的SM2Util工具类

在Java Spring Boot项目中,我们可以通过使用SM2Util工具类来实现对数据的加密和解密。下面是一个简单的示例代码:

import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.util.encoders.Hex;
import org.bouncycastle.util.encoders.UrlBase64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.*;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;

public class SM2Util {

    private static final Logger logger = LoggerFactory.getLogger(SM2Util.class);

    private static final String ALGORITHM_NAME = "SM2";
    private static final String ALGORITHM_PROVIDER = "BC";

    private static final int KEY_SIZE = 256;

    // 生成密钥对
    public static Map<String, String> generateKeyPair() {
        Security.addProvider(new BouncyCastleProvider());
        KeyPairGenerator keyPairGenerator;
        try {
            keyPairGenerator = KeyPairGenerator.getInstance(ALGORITHM_NAME, ALGORITHM_PROVIDER);
        } catch (NoSuchAlgorithmException e) {
            logger.error("NoSuchAlgorithmException: {}", e);
            return null;
        }
        keyPairGenerator.initialize(KEY_SIZE);
        KeyPair keyPair = keyPairGenerator.generateKeyPair();
        PublicKey publicKey = keyPair.getPublic();
        PrivateKey privateKey = keyPair.getPrivate();
        Map<String, String> keyMap = new HashMap<>();
        keyMap.put("publicKey", UrlBase64.encode(publicKey.getEncoded()).toString());
        keyMap.put("privateKey", UrlBase64.encode(privateKey.getEncoded()).toString());
        return keyMap;
    }

    // 公钥加密
    public static byte[] encrypt(byte[] data, String publicKey) {
        try {
            Security.addProvider(new BouncyCastleProvider());
            X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(UrlBase64.decode(publicKey.getBytes()));
            KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM_NAME, ALGORITHM_PROVIDER);
            PublicKey pubKey = keyFactory.generatePublic(x509EncodedKeySpec);
            Cipher cipher = Cipher.getInstance(ALGORITHM_NAME, ALGORITHM_PROVIDER);
            cipher.init(Cipher.ENCRYPT_MODE, pubKey);
            return cipher.doFinal(data);
        } catch (NoSuchAlgorithmException | NoSuchProviderException | NoSuchPaddingException | InvalidKeySpecException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException e) {
            logger.error("Encrypt error: {}", e);
            return null;
        }
    }

    // 私钥解密
    public static byte[] decrypt(byte[] data, String privateKey) {
        try {
            Security.addProvider(new BouncyCastleProvider());
            PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(UrlBase64.decode(privateKey.getBytes()));
            KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM_NAME, ALGORITHM_PROVIDER);
            PrivateKey priKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
            Cipher cipher = Cipher.getInstance(ALGORITHM_NAME, ALGORITHM_PROVIDER);
            cipher.init(Cipher.DECRYPT_MODE, priKey);
            return cipher.doFinal(data);
        } catch (NoSuchAlgorithmException | NoSuchProviderException | NoSuchPaddingException | InvalidKeySpecException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException e) {
            logger.error("Decrypt error: {}", e);
            return