鼠鼠昨晚闲着无聊逛了一下大学生创业大赛,看到了一个名为《基于国密算法和区块链的党建信信息安全防护系统》的项目,鼠鼠最近沉迷于搭建安全性极高的聊天平台,于是就了解了一下国密算法,并且写下了这篇文章
国密算法概述及与国际算法对比
一、SM2 – 椭圆曲线公钥密码算法
作用
- 数字签名:提供数据完整性和不可否认性。
- 密钥交换:支持双方安全地协商共享密钥。
- 公钥加密:用于保护信息的机密性。
对比国际算法
- RSA:广泛应用于公钥加密和数字签名,但随着密钥长度增加,计算复杂度大幅上升。
- ECC (椭圆曲线密码):SM2 基于 ECC,具有更短的密钥长度却提供相同的安全级别。例如,256位的 SM2 提供了相当于 3072 位 RSA 的安全性。
二、SM3 – 密码杂凑算法
作用
- 数据完整性验证:通过生成输入数据的消息摘要来确保数据未被篡改。
- 消息认证:结合对称或非对称加密技术,实现消息来源的身份验证。
对比国际算法
- SHA-256:是目前广泛使用的哈希函数之一。SM3 和 SHA-256 在设计上有相似之处,但 SM3 针对中国市场需求进行了优化,理论上具备更高的抗攻击能力。
三、SM4 – 对称分组密码算法
作用
- 数据加密:用于保护存储和传输中的敏感信息。
- 密钥管理:配合其他算法使用时,可作为基础的加密层保障密钥的安全传输。
对比国际算法
- AES (高级加密标准):AES 是全球范围内最流行的对称加密算法之一,支持128、192和256位密钥长度。SM4 只支持128位密钥长度,但在性能和安全性方面与 AES 相当。
Java实践
pom文件
复制代码 隐藏代码
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.xiaoz</groupId>
<artifactId>Safety</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>21</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.26</version>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.70</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.5.18</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.5.18</version>
</dependency>
</dependencies>
</project>
Java代码
复制代码 隐藏代码
import cn.hutool.core.codec.Base64;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.SM2;
import cn.hutool.crypto.digest.SM3;
import cn.hutool.crypto.symmetric.SM4;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.crypto.KeyAgreement;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.spec.ECGenParameterSpec;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionException;
public class NationalEncryption {
static {
SecureUtil.addProvider(new BouncyCastleProvider());
}
private static final Logger log = LoggerFactory.getLogger("国密算法");
private final static String key = "这是一个测试";
//模拟RSA
public void mrsa(){
SM2 sm2 = new SM2();
//生成密钥对
String privatekey = sm2.getPrivateKeyBase64();
String publickey = sm2.getPublicKeyBase64();
log.info("私钥:{}",privatekey);
log.info("公钥:{}",publickey);
//公钥加密
byte[] encryptData = sm2.encrypt(key.getBytes(StandardCharsets.UTF_8), KeyType.PublicKey);
log.info("加密后的数据为:{}", Base64.encode(encryptData));
}
//密钥交换
public void change() throws Exception {
//初始化密钥对生成器
KeyPairGenerator kPG = KeyPairGenerator.getInstance("ECDH", "BC");
ECGenParameterSpec sm2p256v1 = new ECGenParameterSpec("sm2p256v1");
kPG.initialize(sm2p256v1,new SecureRandom());
//用户A
KeyPair AkeyPair = kPG.generateKeyPair();//获取密钥对
PublicKey aPublic = AkeyPair.getPublic();
PrivateKey aPrivate = AkeyPair.getPrivate();
//用户B
KeyPair bkeyPair = kPG.generateKeyPair();
PublicKey bPublic = bkeyPair.getPublic();
PrivateKey bPrivate = bkeyPair.getPrivate();
//交换密钥
//(以A为第一视角交换B)
KeyAgreement Aagreement = KeyAgreement.getInstance("ECDH", "BC");
Aagreement.init(aPrivate);
Aagreement.doPhase(bPublic,true);
byte[] ABgenerateSecret = Aagreement.generateSecret();
//(以B为第一视角交换A)
KeyAgreement Bagreement = KeyAgreement.getInstance("ECDH", "BC");
Bagreement.init(bPrivate);
Bagreement.doPhase(aPublic,true);
byte[] BgenerateSecret = Bagreement.generateSecret();
//输出测试
log.info("A计算出的密钥为:{}", Base64.encode(ABgenerateSecret));
log.info("B计算出的密钥为:{}",Base64.encode(BgenerateSecret));
//使用sm3算法获取信息摘要
SM3 sm3 = new SM3();
byte[] sourkey = sm3.digest(ABgenerateSecret);
log.info("协商密钥的信息摘要为:{}",Base64.encode(key));
byte[] endkey = CompletableFuture.supplyAsync( ()->{
byte[] bytes = new byte[16];
int jsq = 0;
for (byte k : sourkey){
if (jsq >= 16) break;
bytes[jsq] = k;
jsq = jsq+1;
}
return bytes;
} ).join();
log.info("m4算法使用的密钥为:{}",Base64.encode(endkey));
//使用sm4加密字符串(需要密钥为16字节)
SM4 sm4 = new SM4(endkey);
String s = sm4.encryptBase64(key);
log.info("sm4加密后的信息为:{}",s);
}
}
关于代码的解释
介绍
此文档提供了一个基于 Hutool 库实现的 Java 示例,展示了如何使用国家密码局标准的 SM2, SM3 和 SM4 算法进行加密操作。这些算法分别用于非对称加密(SM2)、消息摘要生成(SM3)和对称加密(SM4)。此外,还展示了如何利用 ECDH 协议完成密钥交换。
主要类和方法
NationalEncryption 类
mrsa
方法
模拟 RSA 加密过程,实际上使用的是 SM2 算法:
- 功能:生成密钥对,并用公钥加密指定的信息。
- 步骤:
- 创建 SM2 实例并生成密钥对。
- 打印私钥和公钥。
- 使用公钥加密信息,并打印加密后的数据。
change
方法
实现了密钥协商与信息加密:
- 功能:通过 ECDH 协议进行密钥交换,然后使用 SM3 生成摘要,并最终使用 SM4 对信息进行加密。
- 步骤:
- 初始化密钥对生成器,使用
"sm2p256v1"
曲线参数。 - 分别为用户 A 和 B 生成密钥对。
- 使用 ECDH 协议计算共享密钥。
- 使用 SM3 计算共享密钥的消息摘要。
- 截取前 16 字节作为 SM4 的密钥。
- 使用 SM4 加密信息并打印结果。
- 初始化密钥对生成器,使用
参数解释
KeyType.PublicKey
- 作用:指定使用公钥进行加密或解密操作。
Base64.encode()
- 作用:将字节数组编码为 Base64 字符串,便于存储或传输。
SecureRandom
- 作用:提供一个强随机数生成器,用于初始化密钥对生成器。
KeyAgreement.getInstance("ECDH", "BC")
- 作用:获取一个 ECDH 密钥协商协议的实例,
"BC"
指定使用 BouncyCastle 提供者。
Aagreement.init(aPrivate)
和 Bagreement.init(bPrivate)
- 作用:初始化密钥协商协议,使用各自的私钥。
Aagreement.doPhase(bPublic,true)
和 Bagreement.doPhase(aPublic,true)
- 作用:执行密钥协商的一个阶段,传入对方的公钥。
ABgenerateSecret
和 BgenerateSecret
- 作用:存储通过密钥协商得到的共享密钥。
SM3 sm3 = new SM3()
- 作用:创建 SM3 实例用于生成消息摘要。
CompletableFuture.supplyAsync()
- 作用:异步地截取共享密钥的消息摘要的前 16 字节,虽然在这个场景下并不需要异步处理,但这里展示了如何结合异步编程来实现特定逻辑。
SM4 sm4 = new SM4(endkey)
- 作用:创建 SM4 实例,使用之前生成的 16 字节密钥进行信息加密。
执行结果预览
复制代码 隐藏代码
20:25:29.321 [main] INFO 国密算法 -- A计算出的密钥为:YI7H7nOPvfmy/9lynC9PArzlq0yIx1g8TWVtOyB3iQY=
20:25:29.329 [main] INFO 国密算法 -- B计算出的密钥为:YI7H7nOPvfmy/9lynC9PArzlq0yIx1g8TWVtOyB3iQY=
20:25:29.344 [main] INFO 国密算法 -- 协商密钥的信息摘要为:44GT44KM44Gv44OG44K544OI44Gn44GZ
20:25:29.347 [main] INFO 国密算法 -- m4算法使用的密钥为:IsjicN+tpI1AxFvF8J2E8w==
20:25:29.368 [main] INFO 国密算法 -- sm4加密后的信息为:6AinKttABwlMPUAx/CBndz8ivoiZoEGUHb4e4MzqM+E=
扫码免费获取资源:
