搜索
新闻详情

国密SM2的调用及SM2、SM3、SM4使用场景

33
发表时间:2022-12-09 08:37作者:全球芯 | glochip.com网址:http://glochip.com/news/

SM2是非对称加密算法,对应应用层程序员来说,使用逻辑和RSA一样。


他的最主要的功能:


①非对称加密;


②签名和验签


对于应用层程序员来说,必须熟悉他的使用,以及他的应用领域,一般在写一个安全的应用时,如果单单使用SM2是不安全的,基本上SM2、SM3、SM4都会同时使用。一般都是用SM4对数据内容加密,使用SM3,对内容进行摘要,再使用SM2,对摘要进行签名。这个是数据发送端做的事情。接收端,先用SM2,对摘要进行验签,验签成功后,就做到了防抵赖,对发送过来的内容进行SM3摘要,看下生成的摘要和验签后的摘要是否一致,用于防篡改。


大体逻辑就是这样的。


另外SM4在加密解密需要相同的密钥,这个我们可以通过编写密钥交换模块实现生成相同的密钥。用于SM4对称加密。


对于应用层来说,说白了就是把RSA换成SM2、把MD5换成SM3,把AES换成SM4,这下大家明白了吧。


这里使用hutool这个库进行SM2的操作!


关于非对称加密的公钥和私钥,可以使用hutool生成,也可以使用openssl生成

openssl生成SM2公钥私钥:


openssl ecparam -genkey -name SM2 -out priv.key

openssl ec -in priv.key -pubout -out pub.key

生成的密钥如下:


-----BEGIN PUBLIC KEY-----

MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAE5SMhCzQHRkg5cjVY4NgnZbniyslJ

G9hsmcibn8Q/vpqUOV7jE428SuQ9qo/gH9US3oVoEC40xmmJ6yswZhG1GA==

-----END PUBLIC KEY-----

-----BEGIN EC PARAMETERS-----

BggqgRzPVQGCLQ==

-----END EC PARAMETERS-----

-----BEGIN EC PRIVATE KEY-----

MHcCAQEEIE8DQeWXexdeDsDh/e/SeZsT3SXFFxYTPvQrp2wO3Zc9oAoGCCqBHM9V

AYItoUQDQgAE5SMhCzQHRkg5cjVY4NgnZbniyslJG9hsmcibn8Q/vpqUOV7jE428

SuQ9qo/gH9US3oVoEC40xmmJ6yswZhG1GA==

-----END EC PRIVATE KEY-----

关于非对称还要注意几点:


公钥是通过私钥产生的;


公钥加密,私钥解密是加密的过程


私钥加密,公钥解密是签名的过程;


源码如下:


package cn.it1995;

import cn.hutool.core.codec.Base64;

import cn.hutool.core.util.HexUtil;

import cn.hutool.core.util.StrUtil;

import cn.hutool.crypto.SecureUtil;

import cn.hutool.crypto.SmUtil;

import cn.hutool.crypto.asymmetric.KeyType;

import cn.hutool.crypto.asymmetric.SM2;

import javax.swing.*;

import java.security.KeyPair;

public class Main {

    static String txt = "Hello World";

    /***

     * 随机生成的密钥对加密或解密

     */

    public static void test1(){

        SM2 sm2 = SmUtil.sm2();

        System.out.println("私钥:" + sm2.getPrivateKey());

        System.out.println("公钥:" + sm2.getPublicKey());

        String encryptStr = sm2.encryptBcd(txt, KeyType.PublicKey);

        String decryptStr = StrUtil.utf8Str(sm2.decryptFromBcd(encryptStr, KeyType.PrivateKey));

        System.out.println("密文:" + encryptStr);

        System.out.println("明文:" + decryptStr);

    }

    /***

     * 自定义密钥对加密或解密

     */

    public static void test2(){

        KeyPair pair = SecureUtil.generateKeyPair("SM2");

        byte[] privateKey = pair.getPrivate().getEncoded();

        byte[] publicKey = pair.getPublic().getEncoded();

        System.out.println("私钥:");

        for(Integer i = 0; i < privateKey.length; i++){

            System.out.print(privateKey[i] + " ");

        }

        System.out.println();

        System.out.println("公钥:");

        for(Integer i = 0; i < publicKey.length; i++){

            System.out.print(publicKey[i] + " ");

        }

        System.out.println();

        SM2 sm2 = SmUtil.sm2(privateKey, publicKey);

        String encryptStr = sm2.encryptBcd(txt, KeyType.PublicKey);

        String decryptStr = StrUtil.utf8Str(sm2.decryptFromBcd(encryptStr, KeyType.PrivateKey));

        System.out.println("密文:" + encryptStr);

        System.out.println("明文:" + decryptStr);

    }

    /***

     * 使用OpenSSL生成的SM2公钥和私钥加密或解密

     */

    public static void test3(){

        String privateKey = "MHcCAQEEIE8DQeWXexdeDsDh/e/SeZsT3SXFFxYTPvQrp2wO3Zc9oAoGCCqBHM9VAYItoUQDQgAE5SMhCzQHRkg5cjVY4NgnZbniyslJG9hsmcibn8Q/vpqUOV7jE428SuQ9qo/gH9US3oVoEC40xmmJ6yswZhG1GA==";

        String publicKey = "MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAE5SMhCzQHRkg5cjVY4NgnZbniyslJG9hsmcibn8Q/vpqUOV7jE428SuQ9qo/gH9US3oVoEC40xmmJ6yswZhG1GA==";

        SM2 sm2 = SmUtil.sm2(Base64.decode(privateKey), Base64.decode(publicKey));

        String encryptStr = sm2.encryptBcd(txt, KeyType.PublicKey);

        String decryptStr = StrUtil.utf8Str(sm2.decryptFromBcd(encryptStr, KeyType.PrivateKey));

        System.out.println("密文:" + encryptStr);

        System.out.println("明文:" + decryptStr);

    }

    /***

     * 随机密钥 签名和验签

     */

    public static void test4(){

        SM2 sm2 = SmUtil.sm2();

        String sign = sm2.signHex(HexUtil.encodeHexStr(txt));

        System.out.println("sign:" + sign);

        boolean verify = sm2.verifyHex(HexUtil.encodeHexStr(txt), sign);

        System.out.println("verify:" + verify);

    }

    /***

     * 自定义密钥对 签名和验签

     */

    public static void test5(){

        KeyPair pair = SecureUtil.generateKeyPair("SM2");

        final SM2 sm2 = new SM2(pair.getPrivate(), pair.getPublic());

        byte[] sign = sm2.sign(txt.getBytes());

        System.out.println("sign");

        for(Integer i = 0; i < sign.length; i++){

            System.out.print(sign[i] + " ");

        }

        System.out.println();

        boolean verify = sm2.verify(txt.getBytes(), sign);

        System.out.print("verify:" + verify);

    }

    /**

     * OpenSSL密钥对 签名和验签

     */

    public static void test6(){

        String privateKey = "MHcCAQEEIE8DQeWXexdeDsDh/e/SeZsT3SXFFxYTPvQrp2wO3Zc9oAoGCCqBHM9VAYItoUQDQgAE5SMhCzQHRkg5cjVY4NgnZbniyslJG9hsmcibn8Q/vpqUOV7jE428SuQ9qo/gH9US3oVoEC40xmmJ6yswZhG1GA==";

        String publicKey = "MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAE5SMhCzQHRkg5cjVY4NgnZbniyslJG9hsmcibn8Q/vpqUOV7jE428SuQ9qo/gH9US3oVoEC40xmmJ6yswZhG1GA==";

        SM2 sm2 = SmUtil.sm2(Base64.decode(privateKey), Base64.decode(publicKey));

        byte[] sign = sm2.sign(txt.getBytes());

        System.out.println("sign");

        for(Integer i = 0; i < sign.length; i++){

            System.out.print(sign[i] + " ");

        }

        System.out.println();

        boolean verify = sm2.verify(txt.getBytes(), sign);

        System.out.print("verify:" + verify);

    }

    /***

     * 分开的:私钥签名,公钥验签

     * 密钥使用OpenSSL生成

     */

    public static void test7(){

        String privateKey = "MHcCAQEEIE8DQeWXexdeDsDh/e/SeZsT3SXFFxYTPvQrp2wO3Zc9oAoGCCqBHM9VAYItoUQDQgAE5SMhCzQHRkg5cjVY4NgnZbniyslJG9hsmcibn8Q/vpqUOV7jE428SuQ9qo/gH9US3oVoEC40xmmJ6yswZhG1GA==";

        String publicKey = "MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAE5SMhCzQHRkg5cjVY4NgnZbniyslJG9hsmcibn8Q/vpqUOV7jE428SuQ9qo/gH9US3oVoEC40xmmJ6yswZhG1GA==";

        SM2 sm2Sign = SmUtil.sm2(Base64.decode(privateKey), null);

        sm2Sign.usePlainEncoding();

        byte[] sign = sm2Sign.sign(txt.getBytes(), null);

        System.out.println("sign");

        for(Integer i = 0; i < sign.length; i++){

            System.out.print(sign[i] + " ");

        }

        System.out.println();

        SM2 sm2 = SmUtil.sm2(null, Base64.decode(publicKey));

        sm2.usePlainEncoding();

        boolean verify = sm2.verify(txt.getBytes(), sign);

        System.out.print("verify:" + verify);

    }

    public void test8(){

    }

    public static void main(String[] args) {

        test1();

        System.out.println("--------------------华丽的分割线------------------------");

        test2();

        System.out.println("--------------------华丽的分割线------------------------");

        test3();

        System.out.println("--------------------华丽的分割线------------------------");

        test4();

        System.out.println("--------------------华丽的分割线------------------------");

        test5();

        System.out.println("--------------------华丽的分割线------------------------");

        test6();

        System.out.println("--------------------华丽的分割线------------------------");

        test7();

    }

}

程序运行如下:


D:\java8\content\bin\java.exe -javaagent:D:\idea\content\lib\idea_rt.jar=50163:D:\idea\content\bin -Dfile.encoding=UTF-8 -classpath D:\java8\content\jre\lib\charsets.jar;D:\java8\content\jre\lib\deploy.jar;D:\java8\content\jre\lib\ext\access-bridge-64.jar;D:\java8\content\jre\lib\ext\cldrdata.jar;D:\java8\content\jre\lib\ext\dnsns.jar;D:\java8\content\jre\lib\ext\jaccess.jar;D:\java8\content\jre\lib\ext\jfxrt.jar;D:\java8\content\jre\lib\ext\localedata.jar;D:\java8\content\jre\lib\ext\nashorn.jar;D:\java8\content\jre\lib\ext\sunec.jar;D:\java8\content\jre\lib\ext\sunjce_provider.jar;D:\java8\content\jre\lib\ext\sunmscapi.jar;D:\java8\content\jre\lib\ext\sunpkcs11.jar;D:\java8\content\jre\lib\ext\zipfs.jar;D:\java8\content\jre\lib\javaws.jar;D:\java8\content\jre\lib\jce.jar;D:\java8\content\jre\lib\jfr.jar;D:\java8\content\jre\lib\jfxswt.jar;D:\java8\content\jre\lib\jsse.jar;D:\java8\content\jre\lib\management-agent.jar;D:\java8\content\jre\lib\plugin.jar;D:\java8\content\jre\lib\resources.jar;D:\java8\content\jre\lib\rt.jar;D:\IDEAProject\SM2Demo\target\classes;D:\newGenRepository\repository\cn\hutool\hutool-all\5.7.6\hutool-all-5.7.6.jar;D:\newGenRepository\repository\org\bouncycastle\bcprov-jdk15to18\1.68\bcprov-jdk15to18-1.68.jar cn.it1995.Main

私钥:EC Private Key [69:a6:2d:32:b5:e8:19:e0:69:a8:a1:f4:ad:2e:60:eb:9d:49:b2:2a]

            X: 8b9cd15f1f6cc97674c0f0dd1613890700805ecbfb7368eade20fa91565c1d49

            Y: 7ca52554e76f04471b69ef8b042080e596937d4d7fd3311c642d5b6a2b2c781d

公钥:EC Public Key [69:a6:2d:32:b5:e8:19:e0:69:a8:a1:f4:ad:2e:60:eb:9d:49:b2:2a]

            X: 8b9cd15f1f6cc97674c0f0dd1613890700805ecbfb7368eade20fa91565c1d49

            Y: 7ca52554e76f04471b69ef8b042080e596937d4d7fd3311c642d5b6a2b2c781d

密文:043AB278DCB9C19E64251B406DB855873AB65BD302CD321ACB509A12449559AD67C7EB8CA0FBE290D06BA9750D38EB70A69DC14C0ECF01803DA4971D471F0C3303D0C69A1001DACC048AECAA0F191196041DA367BBEB100F7C02506B57F51568F17A7C1024E90D30F7D20006

明文:Hello World

--------------------华丽的分割线------------------------

私钥:

48 -127 -109 2 1 0 48 19 6 7 42 -122 72 -50 61 2 1 6 8 42 -127 28 -49 85 1 -126 45 4 121 48 119 2 1 1 4 32 -88 107 3 126 93 -49 -79 -127 52 60 55 125 -50 38 78 68 -34 81 -84 -97 -82 69 0 3 -72 40 23 15 -41 112 -96 -97 -96 10 6 8 42 -127 28 -49 85 1 -126 45 -95 68 3 66 0 4 -35 21 15 107 92 -61 82 34 -25 34 24 42 122 -18 88 117 -49 -20 50 -92 -10 -99 77 46 -80 -20 -121 99 13 -114 54 -105 34 -1 -72 77 7 -87 -112 84 -91 64 71 91 40 -78 -126 119 10 -113 97 6 94 -47 12 -8 37 -11 -61 81 96 14 -51 -97

公钥:

48 89 48 19 6 7 42 -122 72 -50 61 2 1 6 8 42 -127 28 -49 85 1 -126 45 3 66 0 4 -35 21 15 107 92 -61 82 34 -25 34 24 42 122 -18 88 117 -49 -20 50 -92 -10 -99 77 46 -80 -20 -121 99 13 -114 54 -105 34 -1 -72 77 7 -87 -112 84 -91 64 71 91 40 -78 -126 119 10 -113 97 6 94 -47 12 -8 37 -11 -61 81 96 14 -51 -97

密文:049625A78A0D48E6C41F55A097E6039C84EE6EF402477A2ACB9FF3D319913731750F3ADAB9186190F0B9EDFBC91B66867A323FFE1C01B5F543ED52D27CFAFBE6E9D37FF3B698D4931196D8D68E81A70726DA67F4C4E59F0007AAA06459704DB40DF8E21E81A9970D35EFD0ED

明文:Hello World

--------------------华丽的分割线------------------------

密文:04D10EE79A33A1A8CE7407544908732F039C244C6FD04D59D5586B701455432209FA93B57142410E69B2BF1B8C8F8176FBDC8AB92FE07BD8C67F3FB121E10E58F1D66AD53E8FDB9408E9CF86E0B463F2968A166BF8F53D8EBEF97E37A325BD49C5F4D6A2AD06851F7DC7E158

明文:Hello World

--------------------华丽的分割线------------------------

sign:3044022025d780da4e9e9756966a5f9bfcfac402bd23fed5ef8e7430605aa409fbddf5ae0220230d911af4bfac036641968fffb7e4fabb17b7e40e85f506bffb8b67932139bf

verify:true

--------------------华丽的分割线------------------------

sign

48 70 2 33 0 -69 -7 -33 44 122 -10 73 60 14 7 -64 58 77 -57 6 -17 16 16 -78 6 114 -80 -100 -118 102 -70 -38 -90 26 -74 -118 91 2 33 0 -127 119 -13 -46 75 27 -52 79 98 42 -68 -44 35 7 -28 -128 -65 84 74 120 -116 -65 -97 77 32 -21 -7 23 -17 59 -84 124

verify:true--------------------华丽的分割线------------------------

sign

48 68 2 32 42 -28 -26 -47 -126 -12 81 -47 68 -80 62 106 -114 -96 -121 -117 -36 -76 77 -35 -106 4 15 103 67 28 -40 -11 -61 26 -96 31 2 32 87 97 -38 20 -111 33 -73 87 100 31 -123 71 110 -118 4 -32 -67 -35 -52 50 -66 -100 99 -83 4 -39 -64 -73 -97 -31 71 67

verify:true--------------------华丽的分割线------------------------

sign

-100 16 -120 93 -98 -23 -87 8 112 75 107 -14 -103 19 -38 -76 115 -86 -128 -120 -95 -20 97 64 123 11 125 -114 18 21 -48 6 87 15 -74 -23 -89 -3 -87 81 -35 0 7 -123 -71 106 8 -31 -96 -12 -49 -70 120 115 -116 47 114 30 6 75 -120 78 117 78

verify:true

Process finished with exit code 0




首页                                    产品展示                                        行业资讯                                   关于我们                                        联系我们
联系电话:
0755-84828852  
0755-84866816

联系方式: 手机号码:13924642346  13872769588
                13924649321  13928483205 联系邮箱:kevin@glochip.com
公司地址:
广东省深圳市龙岗区大运软件小镇1栋401室
(3号线,14号线,16号线,33号线)
网址:www.glochip.com   www.chip.com.cn
全球芯微信公众号
加密芯片 华芯微特   艾迪科泰    博雅科技    恒烁半导体    补丁科技    晶存科技   华大电子    康盈半导体     三星半导体   海力士  镁光科技     南亚科技  铠侠  金士顿   Skyhigh  Netsol
MCU  SRAM MRAM SDRAM DDR1 DDR2 DDR3 DDR4 DDR5 LPDDR3 LPDDR4 LPDDR4X LPDDR5 LPDDR5X NAND NOR eMMC UFS eMCP uMCP