国密SM2/SM3算法

本文介绍了中国国密算法,包括SM1、SM2、SM3、SM4和SM7的特点和应用场景。重点讲解了非对称加密算法SM2及其工具包BouncyCastle的安装与Java代码实现,同时提供了SM3的工具类示例。
摘要由CSDN通过智能技术生成

国密算法

国密算法

分类

1、SM1是一种分组加密算法
对称加密算法中的分组加密算法,其分组长度、秘钥长度都是128bit,算法安全保密强度跟 AES 相当,但是算法不公开,仅以IP核的形式存在于芯片中,需要通过加密芯片的接口进行调用。

采用该算法已经研制了系列芯片、智能IC卡、智能密码钥匙、加密卡、加密机等安全产品,广泛应用于电子政务、电子商务及国民经济的各个应用领域(包括国家政务通、警务通等重要领域)。

2、SM2是非对称加密算法
它是基于椭圆曲线密码的公钥密码算法标准,其秘钥长度256bit,包含数字签名、密钥交换和公钥加密,用于替换RSA/DH/ECDSA/ECDH等国际算法。可以满足电子认证服务系统等应用需求,由国家密码管理局于2010年12月17号发布。

SM2采用的是ECC 256位的一种,其安全强度比RSA 2048位高,且运算速度快于RSA。

3、SM3是一种密码杂凑算法
用于替代MD5/SHA-1/SHA-2等国际算法,适用于数字签名和验证、消息认证码的生成与验证以及随机数的生成,可以满足电子认证服务系统等应用需求,于2010年12月17日发布。

它是在SHA-256基础上改进实现的一种算法,采用Merkle-Damgard结构,消息分组长度为512bit,输出的摘要值长度为256bit。

4、SM4是分组加密算法
跟SM1类似,是我国自主设计的分组对称密码算法,用于替代DES/AES等国际算法。SM4算法与AES算法具有相同的密钥长度、分组长度,都是128bit。于2012年3月21日发布,适用于密码应用中使用分组密码的需求。

5、SM7是一种分组加密算法
该算法没有公开。SM7适用于非接IC卡应用包括身份识别类应用(门禁卡、工作证、参赛证),票务类应用(大型赛事门票、展会门票),支付与通卡类应用(积分消费卡、校园一卡通、企业一卡通、公交一卡通)。

6、SM9是基于标识的非对称密码算法
用椭圆曲线对实现的基于标识的数字签名算法、密钥交换协议、密钥封装机制和公钥加密与解密算法,包括数字签名生成算法和验证算法,并给出了数字签名与验证算法及其相应的流程。并提供了相应的流程。可以替代基于数字证书的PKI/CA体系。

SM9主要用于用户的身份认证。据新华网公开报道,SM9的加密强度等同于3072位密钥的RSA加密算法,于2016年3月28日发布。

算法下载地址:http://www.scctc.org.cn/templates/Download/index.aspx?nodeid=71

规范

国标文档中定义国密算法使用256位椭圆曲线;
原文摘抄:

SM2"使用素数域256位椭圆曲线“
SM2标准中规定采用256比特的椭圆曲线域参数,并采用256比特的密码杂凑算法,并规定某些步骤中须采用SM3。

SM2密文由C1、C2、C3三部分构成,如何对SM2密文进行编码在已经公布的两个标准中有所不同,在早期公布的《SM2椭圆曲线公钥密码算法 第4部分:公钥加密算法》中,SM2密文中的三部分依次输出,没有采用如Tag-Length-Value形式的编码,我们称其为Plain编码。在之后公布的GM/T国标中,SM2密文采用ASN.1/DER方式编码。

SM3是国密密码杂凑算法标准,由国家密码管理局于2010年12月公布。SM3的输出杂凑值长度为256比特(32字节),与国际标准SHA-256等长。SM3设计安全性为128比特,安全性与256比特椭圆曲线/SM2、SM4/SMS4、AES-128等同。

工具包BouncyCastle

Java标准库提供了一系列常用的哈希算法。但如果我们要用的某种算法,Java标准库没有提供怎么办,BouncyCastle就是一个提供了很多哈希算法和加密算法的第三方库。它提供了Java标准库没有的一些算法。

安装

方式一

动态安装
引入包,

   <dependency>
            <groupId>org.bouncycastle</groupId>
            <artifactId>bcprov-jdk15to18</artifactId>
            <version>1.71</version>
        </dependency>

最新的包及jdk支持 可以戳 这里
使用时需要通过Security.addProvider(new BouncyCastleProvider())动态加载到jvm

  @Test
    public void case5() throws Exception {
        // 注册BouncyCastle:
        String key="BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB";
        System.out.println(key.length());
        Security.addProvider(new BouncyCastleProvider());
        Cipher cipher = Cipher.getInstance("AES/ECB/PKCS7Padding");
        cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key.getBytes("UTF-8"), "AES"));
        byte[] resultByte = cipher.doFinal("zw".getBytes("UTF-8"));
        System.out.println(Hex.toHexString(resultByte));
    }
方式二

静态安装
(1)去BouncyCastle官网下载provider的包,然后放入$JAVA_HOME\jre\lib\ext目录下;
(2)修改配置文件
java8: %java_home%\jre\lib\security\java.security
java9+: %JAVA_HOME%\conf\security.
加入一行配置:
security.provider.按顺序填数字=org.bouncycastle.jce.provider.BouncyCastleProvider

  @Test
    public void case5() throws Exception {
        String key="BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB";
        System.out.println(key.length());
        Cipher cipher = Cipher.getInstance("AES/ECB/PKCS7Padding");
        cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key.getBytes("UTF-8"), "AES"));
        byte[] resultByte = cipher.doFinal("zw".getBytes("UTF-8"));
     System.out.println(Hex.toHexString(resultByte));
    }

java代码实现

SM2工具类

SM2KeyInfo.java

package com.tom.crypto;

/**
 * @ClassName SM2KeyInfo
 * @Description  生成密钥info
 * @Author tom
 */
public class SM2KeyInfo {
    /**
     *
     *  BC库使用的公钥=64个字节+1个字节(04标志位),BC库使用的私钥=32个字节
     *  SM2秘钥的组成部分有 私钥D 、公钥X 、 公钥Y , 他们都可以用长度为64的16进制的HEX串表示,
     *  SM2公钥并不是直接由X+Y表示 , 而是额外添加了一个头,当启用压缩时:公钥=有头+公钥X ,即省略了公钥Y的部分
     */
    private String publicKeyHex;
    private String privateKeyHex;
    private String pubX;
    private String pubY;

    public SM2KeyInfo() {
    }

    public String getPublicKeyHex() {
        return publicKeyHex;
    }

    public void setPublicKeyHex(String publicKeyHex) {
        this.publicKeyHex = publicKeyHex;
    }

    public String getPrivateKeyHex() {
        return privateKeyHex;
    }

    public void setPrivateKeyHex(String privateKeyHex) {
        this.privateKeyHex = privateKeyHex;
    }

    public String getPubX() {
        return pubX;
    }

    public void setPubX(String pubX) {
        this.pubX = pubX;
    }

    public String getPubY() {
        return pubY;
    }

    public void setPubY(String pubY) {
        this.pubY = pubY;
    }

    @Override
    public String toString() {
        final StringBuffer sb = new StringBuffer("SM2KeyInfo{");
        sb.append("publicKeyHex='").append(publicKeyHex).append('\'');
        sb.append(", privateKeyHex='").append(privateKeyHex).append('\'');
        sb.append(", pubX='
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值