国密算法SM3-java实现

本文介绍了如何在Maven项目中使用Bouncy Castle库的bcprov-jdk15on组件,并展示了SM3算法的运用,包括加密、HMAC和校验过程,重点在于演示如何进行字符串加密和密钥相关操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Maven依赖

<dependency>
    <groupId>org.bouncycastle</groupId>
    <artifactId>bcprov-jdk15on</artifactId>
    <version>1.56</version>
</dependency>

SM3Utils

import org.bouncycastle.crypto.digests.SM3Digest;
import org.bouncycastle.crypto.macs.HMac;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.pqc.math.linearalgebra.ByteUtils;

import java.io.UnsupportedEncodingException;
import java.security.Security;
import java.util.Arrays;

public class SM3Utils {
    private static final String ENCODING = "UTF-8";
    static {
        Security.addProvider(new BouncyCastleProvider());
    }

    /**
     * sm3算法加密
     * @explain
     * @param paramStr 待加密字符串
     * @return 返回加密后,固定长度=32的16进制字符串
     */
    public static String encrypt(String paramStr){
        // 将返回的hash值转换成16进制字符串
        String resultHexString = "";
        try {
            // 将字符串转换成byte数组
            byte[] srcData = paramStr.getBytes(ENCODING);
            // 调用hash()
            byte[] resultHash = hash(srcData);
            // 将返回的hash值转换成16进制字符串
            resultHexString = ByteUtils.toHexString(resultHash);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return resultHexString;
    }

    /**
     * 返回长度=32的byte数组
     * @explain 生成对应的hash值
     * @param srcData
     * @return
     */
    public static byte[] hash(byte[] srcData) {
        SM3Digest digest = new SM3Digest();
        digest.update(srcData, 0, srcData.length);
        byte[] hash = new byte[digest.getDigestSize()];
        digest.doFinal(hash, 0);
        return hash;
    }
    /**
     * sm3算法加密
     * @explain
     * @param paramStr 待加密字符串
     * @param key 密钥
     * @return 返回加密后,固定长度=32的16进制字符串
     */
    public static String encryptPlus(String paramStr,String key){
        // 将返回的hash值转换成16进制字符串
        String resultHexString = "";
        try {
            // 将字符串转换成byte数组
            byte[] srcData = paramStr.getBytes(ENCODING);
            // 调用hash()
            byte[] resultHash = hmac(srcData,key.getBytes(ENCODING));
            // 将返回的hash值转换成16进制字符串
            resultHexString = ByteUtils.toHexString(resultHash);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return resultHexString;
    }

    /**
     * 通过密钥进行加密
     * @explain 指定密钥进行加密
     * @param key 密钥
     * @param srcData 被加密的byte数组
     * @return
     */
    public static byte[] hmac(byte[] key, byte[] srcData) {
        KeyParameter keyParameter = new KeyParameter(key);
        SM3Digest digest = new SM3Digest();
        HMac mac = new HMac(digest);
        mac.init(keyParameter);
        mac.update(srcData, 0, srcData.length);
        byte[] result = new byte[mac.getMacSize()];
        mac.doFinal(result, 0);
        return result;
    }

    /**
     * 判断源数据与加密数据是否一致
     * @explain 通过验证原数组和生成的hash数组是否为同一数组,验证2者是否为同一数据
     * @param srcStr 原字符串
     * @param sm3HexString 16进制字符串
     * @return 校验结果
     */
    public static boolean verify(String srcStr, String sm3HexString) {
        boolean flag = false;
        try {
            byte[] srcData = srcStr.getBytes(ENCODING);
            byte[] sm3Hash = ByteUtils.fromHexString(sm3HexString);
            byte[] newHash = hash(srcData);
            if (Arrays.equals(newHash, sm3Hash)){
                flag = true;
            }
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return flag;
    }

    public static void main(String[] args) {
        String str = "{\"test\":\"001\"}";
        //秘钥
        String key = "key";
        String hex = SM3Utils.encryptPlus(str,key);
        System.out.println("参数:" + str);
        System.out.println("密文:" + hex);
    }

}

很高兴回答你的问题!以下是一个使用算法(SM2-SM3)的Java Demo Maven工程,供您参考: 1. 首先,在pom.xml文件中添加以下依赖: ```xml <dependency> <groupId>com.huawei.security</groupId> <artifactId>sm</artifactId> <version>2.0.5.300</version> </dependency> ``` 2. 创建SM2钥对 ```java import com.huawei.security.sm.SM2KeyPair; import com.huawei.security.sm.SM2PrivateKey; import com.huawei.security.sm.SM2PublicKey; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.Security; public class SM2Demo { public static void main(String[] args) throws NoSuchProviderException, NoSuchAlgorithmException { Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider()); SM2KeyPair sm2KeyPair = new SM2KeyPair(); SM2PublicKey publicKey = sm2KeyPair.getPublicKey(); SM2PrivateKey privateKey = sm2KeyPair.getPrivateKey(); System.out.println("publicKey: " + publicKey.getHexString()); System.out.println("privateKey: " + privateKey.getHexString()); } } ``` 3. SM2加和解 ```java import com.huawei.security.sm.SM2PrivateKey; import com.huawei.security.sm.SM2PublicKey; import com.huawei.security.sm.SM2Engine; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.Security; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.KeyPairGenerator; import javax.crypto.Cipher; import javax.crypto.NoSuchPaddingException; public class SM2Demo { public static void main(String[] args) throws NoSuchProviderException, NoSuchAlgorithmException, InvalidAlgorithmParameterException, InvalidKeyException, NoSuchPaddingException { Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider()); // 创建钥对 KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("EC", "BC"); keyPairGenerator.initialize(256); SM2KeyPair sm2KeyPair = new SM2KeyPair(keyPairGenerator.generateKeyPair()); // 获取公钥和私钥 SM2PublicKey publicKey = sm2KeyPair.getPublicKey(); SM2PrivateKey privateKey = sm2KeyPair.getPrivateKey(); // 加 SM2Engine sm2Engine = new SM2Engine(); Cipher cipher = Cipher.getInstance(sm2Engine.getAlgorithmName(), "BC"); cipher.init(Cipher.ENCRYPT_MODE, publicKey); byte[] plaintext = "Hello, world!".getBytes(); byte[] ciphertext = cipher.doFinal(plaintext); System.out.println("ciphertext: " + new String(ciphertext)); // 解 cipher.init(Cipher.DECRYPT_MODE, privateKey); byte[] decrypted = cipher.doFinal(ciphertext); System.out.println("decrypted: " + new String(decrypted)); } } ``` 4. SM3哈希算法 ```java import com.huawei.security.sm.SM3Digest; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.Security; public class SM3Demo { public static void main(String[] args) throws NoSuchProviderException, NoSuchAlgorithmException { Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider()); // 计算哈希值 SM3Digest sm3Digest = new SM3Digest(); byte[] plaintext = "Hello, world!".getBytes(); sm3Digest.update(plaintext, 0, plaintext.length); byte[] hash = new byte[sm3Digest.getDigestSize()]; sm3Digest.doFinal(hash, 0); System.out.println("hash: " + org.bouncycastle.util.encoders.Hex.toHexString(hash)); } } ``` 希望这个Demo工程能够帮助您使用算法(SM2-SM3)的Java开发。如果您有任何疑问,请随时联系我!
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

人类幼崽养成记

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值