数据加密-国密SM3签名验签

2 篇文章 0 订阅
1 篇文章 0 订阅

1 什么是SM3

SM3算法也是一种哈希算法,中国国家密码管理局在2010年发布,其名称是SM3密码杂凑算法,密码管理局有该算法的详细说明,可以到其网站下载。
本质上是给数据加一个固定长度的指纹,这个固定长度就是256比特。

1.1 处理过程

第一步:填充,使填充后的数据的长度是512的整数倍
先在数据的最尾巴上加一个1;然后把原始数据的长度用64比特表示,放在最后面;再看看现在的数据的长度值离512的整数还差多少个,差多少个就填多少个0在加的这个1和64比特的长度之间。
第二步:分组
把填充后的信息按照512比特一个分组进行分组,如果分成了N组,就是b(0),b(1),b(N-1)
第三步:迭代压缩得到最后的杂凑值(哈希值)
IV(n)=CF(IV(n-1),b(n-1))
如果信息分为N组,那么IV(N)就是最后得到的杂凑值。

理论部分就这么多,摘过来的。。。。。具体算法对我这种小菜鸡来说完全就是天书,各位感兴趣的老铁可以自行研究。

2 SM3工具类实现

这里面我用的方法比较简单,就是简单的签名和验签。复杂的实现方式也有,可以去gitee上看大佬的项目,连接在文章的最下方。

第一步还是导入依赖

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

工具类

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;

/**
 * SM3 工具类
 */
public class Sm3Util {

    /**
     * 编码格式
     */
    private static final String ENCODING = "UTF-8";

    static{
        Security.addProvider(new BouncyCastleProvider());
    }

    /**
     *
     * @param paramStr 要sm3加密的内容
     * @return sm3加密后密文
     */
    public static String encrypt(String paramStr){
        String resultHexString = "";
        try {
            byte[] srcData = paramStr.getBytes(ENCODING);
            byte[] hash = hash(srcData);
            resultHexString = ByteUtils.toHexString(hash);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return resultHexString;
    }

    public static byte[] hash(byte[] srcData){
        SM3Digest sm3Digest = new SM3Digest();
        sm3Digest.update(srcData,0,srcData.length);
        byte[] bytes = new byte[sm3Digest.getDigestSize()];
        sm3Digest.doFinal(bytes,0);
        return bytes;
    }

    /**
     *
     * @param str 明文
     * @param hexString 密文
     * @return 明文密文对比结果
     */
    public static boolean verify(String str,String hexString){
        boolean flag = false;
        try {
            byte[] srcData = str.getBytes(ENCODING);
            byte[] sm3Hash = ByteUtils.fromHexString(hexString);
            byte[] hash = hash(srcData);
            if (Arrays.equals(hash,sm3Hash)){
                flag = true;
            }
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return flag;
    }

}

ok,这就大功告成了,非常简单有木有。最后验证一下。

public static void main(String[] args) {
        String str = "qaz5tgb&^$>:{*&";
        String encrypt = Sm3Util.encrypt(str);
        System.out.println("签名 :"+encrypt);

        boolean verify = Sm3Util.verify(str, encrypt);
        System.out.println("验签结果 :" + verify);
    }

以上就是SM3的实现,对于目前来说可以满足简单要求,想要更丰富的签名和验签功能可以参考这个大佬的项目。

gitee地址:https://gitee.com/ren365880/sm-java/tree/master

后面还会增加实际业务场景中前后端交互的加密解密处理。
我是王同学,喜欢这篇文章的伙伴可以点赞关注,我会经常分享技术相关博客,共同进步。

  • 3
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值