首页 > 编程语言 >国密算法SM3-java实现

国密算法SM3-java实现

时间:2024-05-09 15:06:04浏览次数:25  
标签:java String SM3 return 国密 key hash byte srcData

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);
    }
 
}
复制代码

 

转载:https://blog.csdn.net/yao583224426/article/details/121746882

 

标签:java,String,SM3,return,国密,key,hash,byte,srcData
From: https://www.cnblogs.com/fuanyu/p/18182245

相关文章

  • 国密算法SM4-java实现
    Maven依赖<dependency><groupId>org.bouncycastle</groupId><artifactId>bcprov-jdk15on</artifactId><version>1.56</version></dependency>SM4importjava.io.ByteArrayInputStream;importjava.......
  • Java学设计模式之建造者模式
    一、建造者模式概念1.1什么是建造者模式建造者模式是一种创建型设计模式,用于将一个复杂对象的构建过程与其表示分离,以便同样的构建过程可以创建不同的表示。它允许客户端通过相同的构建过程来构建不同的产品。建造者模式通常涉及以下几个角色:产品(Product):表示被构建的复杂对......
  • [LeetCode] 最短的桥 双BFS Java
    Problem:934.最短的桥目录思路复杂度Code思路先找到第一个岛屿,根据每一个岛屿的岛屿块的位置多源查找这个块与第二个岛屿的距离,先找到的就是最少的距离同时,将已遍历过的岛屿标记为-1,避免重复入队复杂度时间复杂度:添加时间复杂度,示例:$O(n^2)$空间复杂度:添......
  • 国密算法SM2-java实现
    Maven依赖<dependency><groupId>org.bouncycastle</groupId><artifactId>bcprov-jdk15on</artifactId><version>1.56</version></dependency>工具类importjava.math.BigInteger;publicclassUtil{......
  • java测试框架Junit5进阶知识点
    声明参数化导入注解<!--junit5新的编程和扩展模型--><dependency><groupId>org.junit.jupiter</groupId><artifactId>junit-jupiter</artifactId><version>5.8.2</version>......
  • Java-读取resource目录下的文件并返回给前端
    我在项目的resource目录下面放了一个模板文件,用来供用户下载提供一个接口给前端,用来下载在Utils类下面写个方法来读取代码publicstaticvoidgetXMindTemplate(HttpServletResponseresponse){StringfileName="templates/TestCaseTemplate.xmind";//文件名称ClassPa......
  • Java-LocalDateTime时间和时间(时间加减)
    前言一开始使用Date类来表述时间属性一个问题是时间戳的问题,另一个问题是读取Excel数据格式的时候没有那么灵活 1.基本知识LocalDateTime是Java8引入的日期和时间API中的一个类,位于java.time包中。它提供了一种更灵活、更方便的方式来处理日期和时间,相比旧的Date类更为......
  • java 多线程CountDownLatch
     CountDownLatch简介CountDownLatch 是Java中的一个同步工具类,可以用来确保一组线程等待其他线程完成各自工作后再继续执行。CountDownLatch的应用场景CountDownLatch可以被广泛应用于各种多线程协作的场景,例如:主线程等待多个子线程完成后再执行下一步操作。多个子任......
  • Java学设计模式之工厂模式
    一、工厂模式概念工厂模式是一种创建型设计模式,用于创建对象而不需要暴露对象的创建逻辑。它将对象的实例化过程封装在一个单独的类中,使得客户端代码只需通过调用工厂类的方法来获取所需的对象,而无需关心具体的实例化过程。工厂模式通常有三种主要的变体:简单工厂模式、工厂方法......
  • 关于Java Chassis 3的契约优先(API First)开发
    本文分享自华为云社区《JavaChassis3技术解密:契约优先(APIFirst)开发》,作者:liubao68。契约优先(APIFirst)开发是指应用程序开发过程中,将API设计作为第一优先级的任务。契约优先开发随着WebServices概念的发展而不断得到重视,特别是微服务架构出现以后,API设计成为影响功能开放、......