PKI - 一文读懂SM1、SM2、SM3、SM4等国密算法

2024-03-21 23:30

本文主要是介绍PKI - 一文读懂SM1、SM2、SM3、SM4等国密算法,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • Pre
  • 概述
  • S1
  • SM2
  • SM3
  • SM4
  • SM9
  • 使用经验
  • 国密算法的安全性
    • SM2算法的安全性
    • SM3算法的安全性
    • SM4算法的安全性
  • 在Java中使用
    • 引入Bouncy Castle依赖
    • 非对称加密SM2
      • 使用随机生成的密钥对加密或解密
      • 使用自定义密钥对加密或解密
      • SM2签名和验签
      • 自定义密钥对
      • 使用SM2曲线点构建SM2
      • 使用私钥D值签名
      • 使用公钥Q值验证签名
    • 其他格式的密钥
    • 摘要加密算法SM3
    • 对称加密SM4

在这里插入图片描述

Pre

Java - 深入理解加密解密和签名算法


概述

国密即国家密码局认定的国产密码算法。主要有SM1,SM2,SM3,SM4。密钥长度和分组长度均为128位。

国密算法是指国家密码管理局认定的一系列国产密码算法,包括SM1-SM9以及ZUC等。其中

  • SM1、SM4、SM5、SM6、SM7、SM8、ZUC等属于对称密码,
  • SM2、SM9等属于公钥密码 (非对称加密)
  • SM3属于单向散列函数。

目前我国主要使用公开的SM2、SM3、SM4作为商用密码算法。

其中SM1、SM7算法不公开,调用该算法时,需要通过加密芯片的接口进行调用

  • SM2是基于椭圆曲线的公钥密码算法,包括用于数字签名的SM2-1、用于密钥交换的SM2-2和用于公钥密码的SM2-3。

  • SM3是能够计算出256比特的散列值的单向散列函数,主要用于数字签名和消息认证码。

  • SM4是属于对称密码的一种分组密码算法,分组长度和密钥长度均为128比特。

国密算法从SM1-SM4分别实现了对称、非对称、摘要等算法功能,目前已普遍应用于日常工作生活中的各个方面,如工作中使用的VPN,金融业务中的资金流转、刷卡支付,以及门禁设施、身份认证等。


S1

SM1 算法是分组密码算法,分组长度为128位,密钥长度都为 128 比特,算法安全保密强度及相关软硬件实现性能与 AES 相当,算法不公开,仅以IP核的形式存在于芯片中。

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


SM2

可以理解为国产RSA。非对称加密,基于ECC。该算法已公开。由于该算法基于ECC,故其签名速度与秘钥生成速度都快于RSA。

SM2椭圆曲线公钥密码算法是我国自主设计的公钥密码算法,包括SM2-1椭圆曲线数字签名算法,SM2-2椭圆曲线密钥交换协议,SM2-3椭圆曲线公钥加密算法,分别用于实现数字签名密钥协商和数据加密等功能。SM2算法与RSA算法不同的是,SM2算法是基于椭圆曲线上点群离散对数难题,相对于RSA算法,256位的SM2密码强度已经比2048位的RSA密码强度要高,但运算速度快于RSA。

SM3

可以理解为国产MD5。消息摘要。可以用MD5作为对比理解。该算法已公开。校验结果为256位。

SM4

可以理解为国产AES。无线局域网标准的分组数据算法。对称加密,密钥长度和分组长度均为128位。

SM9

一种标识密码(IBE)算法,由国家密码管理局于2016年3月28日发布,相关标准为“GM/T 0044-2016 SM9标识密码算法”。主要用于用户的身份认证。SM9的加密强度等同于3072位密钥的RSA加密算法。


使用经验

一般数据发送端都是用SM4对数据内容加密,使用SM3对内容进行摘要,再使用SM2对摘要进行签名。

一般接收端,先用SM2对摘要进行验签,验签成功后就做到了防抵赖,对发送过来的内容进行SM3摘要,看下生成的摘要和验签后的摘要是否一致,用于防篡改。


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

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

(1)公钥是通过私钥产生的;

(2)公钥加密,私钥解密是加密的过程

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

由于SM1、SM4加解密的分组大小为128bit,故对消息进行加解密时,若消息长度过长,需要进行分组,要消息长度不足,则要进行填充。


国密算法的安全性

国密算法,作为国家层面推广的密码算法标准,其安全性经过了严格的审查和评估。

以下是对SM2、SM3和SM4算法安全性的进一步分析:

SM2算法的安全性

SM2算法是一个基于椭圆曲线的公钥密码算法,其安全性主要依赖于椭圆曲线离散对数问题的难度。与RSA算法相比,SM2算法在相同的安全强度下,所需的密钥长度更短,因此,在加密和签名速度上具有一定的优势。此外,SM2算法在设计时也考虑了多种攻击手段,并采用了相应的防护措施,从而确保了其在实际应用中的安全性。

SM3算法的安全性

SM3算法是一个密码杂凑算法,主要用于数字签名和消息认证等场景。其安全性主要体现在以下几个方面:

  1. 输出长度:SM3算法的输出长度为256比特,相比MD5(128比特)和SHA-1(160比特)算法,其输出长度更长,因此具有更高的安全性。

  2. 碰撞攻击:SM3算法在设计时考虑了碰撞攻击的问题,并采用了相应的防护措施。目前,尚未有公开的针对SM3算法的碰撞攻击方法。

  3. 雪崩效应:SM3算法具有雪崩效应,即输入数据的微小变化会导致输出结果的巨大差异。这一特性使得攻击者难以通过猜测或穷举的方式来破解SM3算法。

SM4算法的安全性

SM4算法是一个分组密码算法,主要用于数据的加密和解密。其安全性主要体现在以下几个方面:

  1. 密钥长度:SM4算法的密钥长度为128比特,与AES算法相同。这一长度的密钥足以抵抗目前已知的所有密码攻击方法。

  2. 分组长度:SM4算法的分组长度也为128比特,这意味着每次加密或解密的数据块大小为128比特。这一分组长度可以确保数据的机密性和完整性。

  3. 加密轮数:SM4算法采用了多轮加密的方式,每轮加密都使用了不同的密钥和加密函数。这种加密方式可以使得攻击者难以通过分析加密过程来破解算法。

  4. 安全性评估:SM4算法已经经过了多轮的安全性评估和审查,其安全性得到了广泛的认可。目前,尚未有公开的针对SM4算法的有效攻击方法。

综上所述,国密算法中的SM2、SM3和SM4算法都具有较高的安全性,可以满足不同场景下的密码应用需求。在实际应用中,可以根据具体的需求和场景选择合适的算法进行使用。

在这里插入图片描述


在Java中使用

Hutool针对Bouncy Castle做了简化包装,用于实现国密算法中的SM2、SM3、SM4。

国密算法工具封装包括:

  • 非对称加密和签名:SM2
  • 摘要签名算法:SM3
  • 对称加密:SM4

国密算法需要引入Bouncy Castle库的依赖。

使用

引入Bouncy Castle依赖

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

说明 bcprov-jdk15to18的版本请前往Maven中央库搜索,查找对应JDK的最新版本。

非对称加密SM2

使用随机生成的密钥对加密或解密

String text = "我是一段测试aaaa";SM2 sm2 = SmUtil.sm2();
// 公钥加密,私钥解密
String encryptStr = sm2.encryptBcd(text, KeyType.PublicKey);
String decryptStr = StrUtil.utf8Str(sm2.decryptFromBcd(encryptStr, KeyType.PrivateKey));

使用自定义密钥对加密或解密

String text = "我是一段测试aaaa";KeyPair pair = SecureUtil.generateKeyPair("SM2");
byte[] privateKey = pair.getPrivate().getEncoded();
byte[] publicKey = pair.getPublic().getEncoded();SM2 sm2 = SmUtil.sm2(privateKey, publicKey);
// 公钥加密,私钥解密
String encryptStr = sm2.encryptBcd(text, KeyType.PublicKey);
String decryptStr = StrUtil.utf8Str(sm2.decryptFromBcd(encryptStr, KeyType.PrivateKey));

SM2签名和验签

String content = "我是Hanley.";
final SM2 sm2 = SmUtil.sm2();
String sign = sm2.signHex(HexUtil.encodeHexStr(content));// true
boolean verify = sm2.verifyHex(HexUtil.encodeHexStr(content), sign);

自定义密钥对

当然,也可以自定义密钥对

String content = "我是Hanley.";
KeyPair pair = SecureUtil.generateKeyPair("SM2");
final SM2 sm2 = new SM2(pair.getPrivate(), pair.getPublic());byte[] sign = sm2.sign(content.getBytes());// true
boolean verify = sm2.verify(content.getBytes(), sign);

使用SM2曲线点构建SM2

使用曲线点构建中的点生成和验证见:https://i.goto327.top/CryptTools/SM2.aspx?tdsourcetag=s_pctim_aiomsg

String privateKeyHex = "FAB8BBE670FAE338C9E9382B9FB6485225C11A3ECB84C938F10F20A93B6215F0";
String x = "9EF573019D9A03B16B0BE44FC8A5B4E8E098F56034C97B312282DD0B4810AFC3";
String y = "CC759673ED0FC9B9DC7E6FA38F0E2B121E02654BF37EA6B63FAF2A0D6013EADF";// 数据和ID此处使用16进制表示
String data = "434477813974bf58f94bcf760833c2b40f77a5fc360485b0b9ed1bd9682edb45";
String id = "31323334353637383132333435363738";final SM2 sm2 = new SM2(privateKeyHex, x, y);
// 生成的签名是64位
sm2.usePlainEncoding();final String sign = sm2.signHex(data, id);
// true
boolean verify = sm2.verifyHex(data, sign)

使用私钥D值签名

//需要签名的明文,得到明文对应的字节数组
byte[] dataBytes = "我是一段测试aaaa".getBytes();
//指定的私钥
String privateKeyHex = "1ebf8b341c695ee456fd1a41b82645724bc25d79935437d30e7e4b0a554baa5e";// 此构造从5.5.9开始可使用
final SM2 sm2 = new SM2(privateKeyHex, null, null);
sm2.usePlainEncoding();
byte[] sign = sm2.sign(dataBytes, null);

使用公钥Q值验证签名

//指定的公钥
String publicKeyHex ="04db9629dd33ba568e9507add5df6587a0998361a03d3321948b448c653c2c1b7056434884ab6f3d1c529501f166a336e86f045cea10dffe58aa82ea13d725363";
//需要加密的明文,得到明文对应的字节数组
byte[] dataBytes = "我是一段测试aaaa".getBytes();
//签名值
String signHex ="2881346e038d2ed706ccdd025f2b1dafa7377d5cf090134b98756fafe084dddbcdba0ab00b5348ed48025195af3f1dda29e819bb66aa9d4d088050ff148482a";final SM2 sm2 = new SM2(null, ECKeyUtil.toSm2PublicParams(publicKeyHex));
sm2.usePlainEncoding();// true
boolean verify = sm2.verify(dataBytes, HexUtil.decodeHex(signHex));

其他格式的密钥

在SM2算法中,密钥的格式分以下几种:

私钥:

  • D值 一般为硬件直接生成的值
  • PKCS#8 JDK默认生成的私钥格式
  • PKCS#1 一般为OpenSSL生成的的EC密钥格式

公钥:

  • Q值 一般为硬件直接生成的值
  • X.509 JDK默认生成的公钥格式
  • PKCS#1 一般为OpenSSL生成的的EC密钥格式

在新版本的Hutool中,SM2的构造方法对这几类的密钥都做了兼容,即用户无需关注密钥类型:

摘要加密算法SM3

//结果为:136ce3c86e4ed909b76082055a61586af20b4dab674732ebd4b599eef080c9be
String digestHex = SmUtil.sm3("aaaaa");

对称加密SM4

String content = "test中文";
SymmetricCrypto sm4 = SmUtil.sm4();String encryptHex = sm4.encryptHex(content);
String decryptStr = sm4.decryptStr(encryptHex, CharsetUtil.CHARSET_UTF_8);

在这里插入图片描述

这篇关于PKI - 一文读懂SM1、SM2、SM3、SM4等国密算法的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/834092

相关文章

不懂推荐算法也能设计推荐系统

本文以商业化应用推荐为例,告诉我们不懂推荐算法的产品,也能从产品侧出发, 设计出一款不错的推荐系统。 相信很多新手产品,看到算法二字,多是懵圈的。 什么排序算法、最短路径等都是相对传统的算法(注:传统是指科班出身的产品都会接触过)。但对于推荐算法,多数产品对着网上搜到的资源,都会无从下手。特别当某些推荐算法 和 “AI”扯上关系后,更是加大了理解的难度。 但,不了解推荐算法,就无法做推荐系

康拓展开(hash算法中会用到)

康拓展开是一个全排列到一个自然数的双射(也就是某个全排列与某个自然数一一对应) 公式: X=a[n]*(n-1)!+a[n-1]*(n-2)!+...+a[i]*(i-1)!+...+a[1]*0! 其中,a[i]为整数,并且0<=a[i]<i,1<=i<=n。(a[i]在不同应用中的含义不同); 典型应用: 计算当前排列在所有由小到大全排列中的顺序,也就是说求当前排列是第

csu 1446 Problem J Modified LCS (扩展欧几里得算法的简单应用)

这是一道扩展欧几里得算法的简单应用题,这题是在湖南多校训练赛中队友ac的一道题,在比赛之后请教了队友,然后自己把它a掉 这也是自己独自做扩展欧几里得算法的题目 题意:把题意转变下就变成了:求d1*x - d2*y = f2 - f1的解,很明显用exgcd来解 下面介绍一下exgcd的一些知识点:求ax + by = c的解 一、首先求ax + by = gcd(a,b)的解 这个

综合安防管理平台LntonAIServer视频监控汇聚抖动检测算法优势

LntonAIServer视频质量诊断功能中的抖动检测是一个专门针对视频稳定性进行分析的功能。抖动通常是指视频帧之间的不必要运动,这种运动可能是由于摄像机的移动、传输中的错误或编解码问题导致的。抖动检测对于确保视频内容的平滑性和观看体验至关重要。 优势 1. 提高图像质量 - 清晰度提升:减少抖动,提高图像的清晰度和细节表现力,使得监控画面更加真实可信。 - 细节增强:在低光条件下,抖

【数据结构】——原来排序算法搞懂这些就行,轻松拿捏

前言:快速排序的实现最重要的是找基准值,下面让我们来了解如何实现找基准值 基准值的注释:在快排的过程中,每一次我们要取一个元素作为枢纽值,以这个数字来将序列划分为两部分。 在此我们采用三数取中法,也就是取左端、中间、右端三个数,然后进行排序,将中间数作为枢纽值。 快速排序实现主框架: //快速排序 void QuickSort(int* arr, int left, int rig

poj 3974 and hdu 3068 最长回文串的O(n)解法(Manacher算法)

求一段字符串中的最长回文串。 因为数据量比较大,用原来的O(n^2)会爆。 小白上的O(n^2)解法代码:TLE啦~ #include<stdio.h>#include<string.h>const int Maxn = 1000000;char s[Maxn];int main(){char e[] = {"END"};while(scanf("%s", s) != EO

秋招最新大模型算法面试,熬夜都要肝完它

💥大家在面试大模型LLM这个板块的时候,不知道面试完会不会复盘、总结,做笔记的习惯,这份大模型算法岗面试八股笔记也帮助不少人拿到过offer ✨对于面试大模型算法工程师会有一定的帮助,都附有完整答案,熬夜也要看完,祝大家一臂之力 这份《大模型算法工程师面试题》已经上传CSDN,还有完整版的大模型 AI 学习资料,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费

dp算法练习题【8】

不同二叉搜索树 96. 不同的二叉搜索树 给你一个整数 n ,求恰由 n 个节点组成且节点值从 1 到 n 互不相同的 二叉搜索树 有多少种?返回满足题意的二叉搜索树的种数。 示例 1: 输入:n = 3输出:5 示例 2: 输入:n = 1输出:1 class Solution {public int numTrees(int n) {int[] dp = new int

Codeforces Round #240 (Div. 2) E分治算法探究1

Codeforces Round #240 (Div. 2) E  http://codeforces.com/contest/415/problem/E 2^n个数,每次操作将其分成2^q份,对于每一份内部的数进行翻转(逆序),每次操作完后输出操作后新序列的逆序对数。 图一:  划分子问题。 图二: 分而治之,=>  合并 。 图三: 回溯:

最大公因数:欧几里得算法

简述         求两个数字 m和n 的最大公因数,假设r是m%n的余数,只要n不等于0,就一直执行 m=n,n=r 举例 以18和12为例 m n r18 % 12 = 612 % 6 = 06 0所以最大公因数为:6 代码实现 #include<iostream>using namespace std;/