课设总结
一、设计方案及可行性分析
课程题目为基于密码算法库的国密算法支持研究 整体内容围绕国密算法展开,通过调用密码算法库自带的函数或命令行,验证密码算法库对国密算法的支持。
如今随着国密算法以sm2 sm3 sm4等密码算法成为国际标准,越来越多的密码算法库已经可以支持国密算法。如使用较为方便的openssl或其分支以国密命名
的gmssl。因此想要找到支持国密算法的密码库并不是一件难事,团队的目标是尽可能在课设准备时间内找到更多支持国密算法的密码库或者工具包,并验证
其可行性。
二、详细设计思路
-
首先将通用的密码算法库按支持的语言进行分配,小组总共三个人员,分别负责python ,c,java,当然还有go和jsp语言,go语言和jsp语言支持国密的方
式比较固定,所以小组采用共同查找资料,并在一台设备上完成的方式。 -
本人实现的库有Bouncycastle,crypto-gmsm,Hutool,crypt++,Gmlib,SM9_FREE,openssl
-
我在本小组实现的部分是java部分,也参与了c部分,c部分整体调节起来比较繁琐,
而java因为语言的特性在linux和windows中的操作流程相差不大。
Java:
Java部分找到的支持国密的库为三个,分别为是bouncycastle,crypto-gmsm,Hutool。三个库支持的国密算法都为sm2,sm3,sm4。其中hutool针对Bouncy
Castle做了简化包装。其中关于国密部分hutool将其整合为SmUtil。在实现java代码过程中,我创建的java项目都是maven,因为创建maven项目可以通过对
pom.xml文件添加dependency,添加依赖可以更加方便的获得我们想要获得的jar包。
实现过程如下:
Bouncycastle
sm2
sm3
sm4
crypto-gmsm:
Hutool:
C:
- C语言部分,我阅读了很多密码算法库的说明,查找到了很多支持国密算法的c语言库,通过阅读函数库说明,在理论上支持国密的函数库有openssl,gmssl,
crypt++,SM9_FREE, Gmlib, Libgcrypt,libtomcrypt-gm,tinycrypt,gmalg, 但是在配置函数库时libtomcrypt-gm和gmalg和libgcrypt都因为没
有无法写出能够调通的测试代码最终失败。C语言部分我参与并完成的函数库有openssl,gmssl,crypt++,和gmlib,SM9_FREE。其中SM9_FREE函数库是
基于Miracl的函数库,因为 源码关系 Miracl密码库 比较庞大,SM9_FREE只截取了其中最核心的部分,包括大整数运算,Fp,Fp2,Fp4域计算以及Fp
和Fp^2上椭圆曲线基础计算等功能。 SM9_FREE正如他的名字一样,他主要支持的算法是SM9。Gmlib支持sm2,sm3,sm4 和zuc本质上也参考了crypt++
openssl。
crypt++:
- 因为crpyt++库他本质上是一个vs项目,通过运行vs项目我们才能得到.a文件,我们需要将.a文件和.h文件结合起来才能运行成功,因为没有成功在openeuler
中配置vs,所以并没有成功的将crypt++函数库转移到unix环境中去,只在windows环境中成功运行。
Gmlib:
- 因为gmlib的函数库需要通过cmake 对应的list文件去生成测试文件,所以在对函数库进行测试的时候可以通过修改cmakelist 文件进而得到想要的test文件
具体只需要修改add_executable和target_link_libraries 函数即可。至于可以修改成什么,再gmlib库中有展示,参考demo文件。
SM9_FREE:
SM9_FREE函数库本身需要通过make函数去生成.a文件。生成.a文件之后只要通过make test 就可以将 自带的SM9.txt文件同.a文件一同编译。生成test 运行./test即可
当然如果直接下载解压SM9_FEEE文件会因为makefile有问题而报错,所以需要对makefile进行修改。具体方法:https://www.cnblogs.com/PiaYie/p/16746335.html
Openssl:
openssl:https://www.cnblogs.com/hzxjkl/p/16828260.html
感悟
如今整体因为国密的通用性,致使现在支持国密算法的函数库也较多,通过学习调用java函数库,寻找可以支持java的密码算法库,锻炼了自己的品行。
在寻找支持java的函数库时,我会在GitHub和gitee寻找代码,仔细阅读每个代码文件,寻找其中调用的函数库。几乎是将github和gitee上的代码全部阅读了一遍。
在寻找支持国密的c语言库的时候,我会尽力看懂每一个支持加密的函数库的帮助文件,通过阅读最新版本的帮助文件和通过下载函数库直接观察其中的.h文件确定
函数库是否支持国密。如今,反观所有的努力,都看似是大海捞针,但是整体不失逻辑。
配置环境和调通代码也是非常困难的,java环境很好配置,但是c的环境就有点困难了。在配置环境库的部分时候因为有的makefile内容和版本不符合,导致花费了很长
的时间。在配置C语言库之前,会单纯的认为将所有的.h文件导入usr/include下就可以直接gcc编译了,但是通过不断查找资料,发现对于静态函数库,还需要将.a文件或.lib
文件进行移动。最后。通过实现一些c语言库也是获得了很多满足感。
当然,也有遗憾,crypt++因为本身的函数库是一个vs项目,只有通过vs运行才可以生成.a文件,但是因为没有在openeuler中成功实现vs的配置,导致最终没有成功
将crypt++在openeuler中运行成功。遗憾还包括一些函数库并没有成功写出测试代码,但是对于函数库本身而言,在帮助文档中或者在函数库代码中都可以寻找到支持国密
的确定信息。
最后本次课程设计也即将结束,希望通过自己的努力可以获得一个不错的成绩。
代码
sm2_demo
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import java.security.*;
import java.security.spec.ECGenParameterSpec;
public class sm2_demo {
private static String M="sm2_demo";
public static void main(String[] args) throws NoSuchAlgorithmException, InvalidAlgorithmParameterException {
SM2Util sm2 = new SM2Util();
final ECGenParameterSpec sm2Spec = new ECGenParameterSpec("sm2p256v1");
// 获取一个椭圆曲线类型的密钥对生成器
final KeyPairGenerator kpg = KeyPairGenerator.getInstance("EC", new BouncyCastleProvider());
// 使用SM2参数初始化生成器
kpg.initialize(sm2Spec);
// 获取密钥对
KeyPair keyPair = kpg.generateKeyPair();
PublicKey publicKey = keyPair.getPublic();
PrivateKey privateKey = keyPair.getPrivate();
String data = sm2.encrypt(publicKey,M);
System.out.println("明文:"+M);
System.out.println("密文:"+data);
String text=sm2.decrypt(privateKey,data);
System.out.println("解密结果"+text);
}
}
SM2Util
import org.bouncycastle.crypto.engines.SM2Engine;
import org.bouncycastle.crypto.params.*;
import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPrivateKey;
import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPublicKey;
import org.bouncycastle.jce.spec.ECParameterSpec;
import org.bouncycastle.util.encoders.Hex;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
public class SM2Util {
/**
* SM2加密算法
* @param publicKey 公钥
* @param data 明文数据
* @return
*/
public String encrypt(PublicKey publicKey, String data) {
ECPublicKeyParameters ecPublicKeyParameters = null;
if (publicKey instanceof BCECPublicKey) {
BCECPublicKey bcecPublicKey = (BCECPublicKey) publicKey;
ECParameterSpec ecParameterSpec = bcecPublicKey.getParameters();
ECDomainParameters ecDomainParameters = new ECDomainParameters(ecParameterSpec.getCurve(),
ecParameterSpec.getG(), ecParameterSpec.getN());
ecPublicKeyParameters = new ECPublicKeyParameters(bcecPublicKey.getQ(), ecDomainParameters);
}
SM2Engine sm2Engine = new SM2Engine();
sm2Engine.init(true, new ParametersWithRandom(ecPublicKeyParameters, new SecureRandom()));
byte[] arrayOfBytes = null;
try {
byte[] in = data.getBytes("utf-8");
arrayOfBytes = sm2Engine.processBlock(in,0, in.length);
} catch (Exception e) {
System.out.println("SM2加密时出现异常:");
}
return Hex.toHexString(arrayOfBytes);
}
/**
* SM2解密算法
* @param privateKey 私钥
* @param cipherData 密文数据
* @return
*/
public String decrypt(PrivateKey privateKey, String cipherData) {
byte[] cipherDataByte = Hex.decode(cipherData);
BCECPrivateKey bcecPrivateKey = (BCECPrivateKey) privateKey;
ECParameterSpec ecParameterSpec = bcecPrivateKey.getParameters();
ECDomainParameters ecDomainParameters = new ECDomainParameters(ecParameterSpec.getCurve(),
ecParameterSpec.getG(), ecParameterSpec.getN());
ECPrivateKeyParameters ecPrivateKeyParameters = new ECPrivateKeyParameters(bcecPrivateKey.getD(),
ecDomainParameters);
SM2Engine sm2Engine = new SM2Engine();
sm2Engine.init(false, ecPrivateKeyParameters);
String result = null;
try {
byte[] arrayOfBytes = sm2Engine.processBlock(cipherDataByte, 0, cipherDataByte.length);
return new String(arrayOfBytes, "utf-8");
} catch (Exception e) {
System.out.println("SM2解密时出现异常");
}
return result;
}
}
sm3_demo
package org.example;
import org.example.SM3Util;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import java.security.*;
import java.security.spec.ECGenParameterSpec;
public class sm3_demo {
private static String test="SM3_demo";
public static void main(String[] args) throws NoSuchAlgorithmException,
InvalidAlgorithmParameterException {
SM3Util sm3 = new SM3Util();
String data = sm3.plainEncrypt(test);
System.out.println("明文:"+test);
System.out.println("哈希值:"+data);
}
}
SM3Util
package org.example;
import org.bouncycastle.crypto.digests.SM3Digest;
import org.bouncycastle.crypto.macs.HMac;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.util.encoders.Hex;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
/**
* @Author: dzy
* @Date: 2018/10/19 16:36
* @Describe: SM3工具类(杂凑算法-hash算法)
*/
public class SM3Util {
/**
* 16进制字符串SM3生成HASH签名值算法
* @param hexString 16进制字符串
* @return
*/
public static String hexEncrypt(String hexString) {
byte[] srcData = Hex.decode(hexString);
byte[] encrypt = encrypt(srcData);
String cipherStr = Hex.toHexString(encrypt);
return cipherStr;
}
/**
* 16进制字符串SM3生成HASH签名值算法
* @param hexKey 16进制密钥
* @param hexString 16进制字符串
* @return
*/
public static String hexEncrypt(String hexKey, String hexString) {
byte[] key = Hex.decode(hexKey);
byte[] srcData = Hex.decode(hexString);
byte[] encrypt = encrypt(key, srcData);
String cipherStr = Hex.toHexString(encrypt);
return cipherStr;
}
/**
* 普通文本SM3生成HASH签名算法
* @param plain 待签名数据
* @return
*/
public static String plainEncrypt(String plain) {
// 将返回的hash值转换成16进制字符串
String cipherStr = null;
try {
//将字符串转换成byte数组
byte[] srcData = plain.getBytes(StandardCharsets.UTF_8);
//调用encrypt计算hash
byte[] encrypt = encrypt(srcData);
//将返回的hash值转换成16进制字符串
cipherStr = Hex.toHexString(encrypt);
} catch (Exception e) {
//log.error("将字符串转换为字节时出现异常:", e);
}
return cipherStr;
}
/**
* 普通文本SM3生成HASH签名算法
* @param hexKey 密钥
* @param plain 待签名数据
* @return
*/
public static String plainEncrypt(String hexKey, String plain) {
// 将返回的hash值转换成16进制字符串
String cipherStr = null;
try {
//将字符串转换成byte数组
byte[] srcData = plain.getBytes(StandardCharsets.UTF_8);
//密钥
byte[] key = Hex.decode(hexKey);
//调用encrypt计算hash
byte[] encrypt = encrypt(key, srcData);
//将返回的hash值转换成16进制字符串
cipherStr = Hex.toHexString(encrypt);
} catch (Exception e) {
//log.error("将字符串转换为字节时出现异常:", e);
}
return cipherStr;
}
/**
* SM3计算hashCode
* @param srcData 待计算数据
* @return
*/
public static byte[] encrypt(byte[] srcData) {
SM3Digest sm3Digest = new SM3Digest();
sm3Digest.update(srcData, 0, srcData.length);
byte[] encrypt = new byte[sm3Digest.getDigestSize()];
sm3Digest.doFinal(encrypt, 0);
return encrypt;
}
/**
* 通过密钥进行加密
* @param key 密钥byte数组
* @param srcData 被加密的byte数组
* @return
*/
public static byte[] encrypt(byte[] key, byte[] srcData) {
KeyParameter keyParameter = new KeyParameter(key);
SM3Digest digest = new SM3Digest();
HMac mac = new HMac(digest);
mac.init(keyParameter);
mac.update(srcData, 0, srcData.length);
byte[] result = new byte[mac.getMacSize()];
mac.doFinal(result, 0);
return result;
}
/**
* SM3计算hashCode
* @param srcData 待计算数据
* @return
* @throws Exception
*/
public static byte[] encrypt_0(byte[] srcData) throws Exception {
MessageDigest messageDigest = MessageDigest.getInstance("SM3", "BC");
byte[] digest = messageDigest.digest(srcData);
return digest;
}
}
sm4_demo
package org.example;
import java.security.*;
import java.security.spec.ECGenParameterSpec;
public class sm4_demo {
private static String test= "SM4_test_zhl1321";
private static String mykey= "6cef39eb85614df44f6b0f6babcd89b6";
public static void main(String[] args) throws NoSuchAlgorithmException,
InvalidAlgorithmParameterException {
SM4Util sm4 = new SM4Util();
//SM3Util sm3 = new SM3Util();
//String data_in = sm3.plainEncrypt(test);
//String data = sm4.encryptByEcb(data_in,mykey);
String x16 = sm4.strToHexadecimal(test);
//System.out.println(x16);
String data = sm4.encryptByEcb(x16,mykey);
System.out.println("明文:"+test);
//System.out.println("摘 要:"+data_in);
System.out.println("密文:"+data);
String text_16 = sm4.decryptByEcb(data,mykey);
//System.out.println(text_16);
//System.out.println(x16.equals(text_16.toUpperCase()));
String text = sm4.hexadecimalToStr(text_16.toUpperCase());
System.out.println("解密结果:"+text);
}
}
SM4Util
Package org.example;
import org.bouncycastle.crypto.engines.SM4Engine;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.util.encoders.Hex;
/**
* @Author: dzy
* @Date: 2018/10/9 16:41
* @Describe: SM4算法
*/
public class SM4Util {
//加解密的字节快大小
public static final int BLOCK_SIZE = 16;
/**
* SM4ECB加密算法
* @param in 待加密内容
* @param keyBytes 密钥
* @return
*/
public static byte[] encryptByEcb0(byte[] in, byte[] keyBytes) {
SM4Engine sm4Engine = new SM4Engine();
sm4Engine.init(true, new KeyParameter(keyBytes));
int inLen = in.length;
byte[] out = new byte[inLen];
int times = inLen / BLOCK_SIZE;
for (int i = 0; i < times; i++) {
sm4Engine.processBlock(in, i * BLOCK_SIZE, out, i * BLOCK_SIZE);
}
return out;
}
/**
* SM4ECB加密算法
* @param in 待加密内容
* @param keyBytes 密钥
* @return
*/
public static String encryptByEcb(byte[] in, byte[] keyBytes) {
byte[] out = encryptByEcb0(in, keyBytes);
String cipher = Hex.toHexString(out);
return cipher;
}
/**
* SM4的ECB加密算法
* @param content 待加密内容
* @param key 密钥
* @return
*/
public static String encryptByEcb(String content, String key) {
byte[] in = Hex.decode(content);
byte[] keyBytes = Hex.decode(key);
String cipher = encryptByEcb(in, keyBytes);
return cipher;
}
/**
* SM4的ECB解密算法
* @param in 密文内容
* @param keyBytes 密钥
* @return
*/
public static byte[] decryptByEcb0(byte[] in, byte[] keyBytes) {
SM4Engine sm4Engine = new SM4Engine();
sm4Engine.init(false, new KeyParameter(keyBytes));
int inLen = in.length;
byte[] out = new byte[inLen];
int times = inLen / BLOCK_SIZE;
for (int i = 0; i < times; i++) {
sm4Engine.processBlock(in, i * BLOCK_SIZE, out, i * BLOCK_SIZE);
}
return out;
}
/**
* SM4的ECB解密算法
* @param in 密文内容
* @param keyBytes 密钥
* @return
*/
public static String decryptByEcb(byte[] in, byte[] keyBytes) {
byte[] out = decryptByEcb0(in, keyBytes);
String plain = Hex.toHexString(out);
return plain;
}
/**
* SM4的ECB解密算法
* @param cipher 密文内容
* @param key 密钥
* @return
*/
public static String decryptByEcb(String cipher, String key) {
byte[] in = Hex.decode(cipher);
byte[] keyBytes = Hex.decode(key);
String plain = decryptByEcb(in, keyBytes);
return plain;
}
public static String strToHexadecimal(String str) {
char[] chars = "0123456789ABCDEF".toCharArray();
StringBuilder sb = new StringBuilder("");
byte[] bs = str.getBytes();
int bit;
for (int i = 0; i < bs.length; i++) {
bit = (bs[i] & 0x0f0) >> 4;
sb.append(chars[bit]);
bit = bs[i] & 0x0f;
sb.append(chars[bit]);
}
return sb.toString().trim();
}
public static String hexadecimalToStr(String hexStr) {
String str = "0123456789ABCDEF";
char[] hexs = hexStr.toCharArray();
byte[] bytes = new byte[hexStr.length() / 2];
int n;
for (int i = 0; i < bytes.length; i++) {
n = str.indexOf(hexs[2 * i]) * 16;
n += str.indexOf(hexs[2 * i + 1]);
bytes[i] = (byte) (n & 0xff);
}
return new String(bytes);
}
}
代码 gmsm-crypt
import cn.superfw.crypto.gmsm.sm2.SM2EngineExtend;
import cn.superfw.crypto.gmsm.sm2.SM2;
import cn.superfw.crypto.gmsm.sm2.SM2KeyPair;
import cn.superfw.crypto.gmsm.sm3.*;
import cn.superfw.crypto.gmsm.sm4.*;
public class Main {
public static void main(String[] args) {
String str = "国密商密";
// 以非压缩公钥模式生成SM2秘钥对(通常), 对方是其他语言(比如GO语言)实现时也能支持
// 压缩模式仅限于数据交互的双方都使用BC库的情况
SM2KeyPair sm2Keys = SM2.generateSm2Keys(false);
String pubKey = sm2Keys.getPublicKey();
String prvKey = sm2Keys.getPrivateKey();
System.out.println("Private Key: " + prvKey);
System.out.println("Public Key: " + pubKey);
System.out.println("\n加密解密测试");
// 加解密测试(C1C2C3模式)
System.out.println("----- C1C2C3模式 -----");
try {
System.out.println("加密前:" + str);
String enData = SM2.encrypt(pubKey, str, SM2EngineExtend.CIPHER_MODE_BC);
System.out.println("加密后:" + enData);
String deData = SM2.decrypt(prvKey, enData, SM2EngineExtend.CIPHER_MODE_BC);
System.out.println("解密后:" + deData);
} catch (Exception e) {
e.printStackTrace();
System.out.println("加解密测试错误");
}
// 加解密测试(C1C3C2模式)
System.out.println("----- C1C3C2模式 -----");
try {
System.out.println("加密前:" + str);
String enData = SM2.encrypt(pubKey, str, SM2EngineExtend.CIPHER_MODE_NORM);
System.out.println("加密后:" + enData);
String deData = SM2.decrypt(prvKey, enData, SM2EngineExtend.CIPHER_MODE_NORM);
System.out.println("解密后:" + deData);
} catch (Exception e) {
e.printStackTrace();
System.out.println("加解密测试错误");
}
System.out.println("\n签名验签测试");
// 签名和验签测试
try {
System.out.println("数据:" + str);
String signStr = SM2.sign(prvKey, str);
System.out.println("签名:" + signStr);
boolean verify = SM2.verify(pubKey, str, signStr);
System.out.println("验签结果:" + verify);
} catch (Exception e) {
e.printStackTrace();
System.out.println("签名和验签测试错误");
}
System.out.println("SM3 国密商密:"+ SM3.digest("国密商密"));
String key = SM4.generateKey();
String input = "国密商密";
System.out.println("Key:" + key);
System.out.println("原文:" + input);
System.out.println();
System.out.println("ECB模式");
String output = SM4.encrypt(key, input);
System.out.println("加密:" + output);
System.out.println("解密:" + SM4.decrypt(key, output));
System.out.println();
System.out.println("CBC模式");
String iv = "12345678123456781234567812345678";
output = SM4.encrypt(key, input, iv);
System.out.println("加密:" + output);
System.out.println("解密:" + SM4.decrypt(key, output, iv));
}
}
pom.xml 需要添加的 依赖
<dependencies>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15to18</artifactId>
<version>1.69</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.5.7</version>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.10</version>
</dependency>
<dependency>
<groupId>cn.superfw</groupId>
<artifactId>crypto-gmsm</artifactId>
<version>1.0</version>
</dependency>
</dependencies>
代码hutool
import cn.hutool.core.util.CharsetUtil;
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 cn.hutool.crypto.symmetric.SymmetricCrypto;
import org.apache.commons.codec.binary.Base64;
import java.security.KeyPair;
/**
* <pre>
* hutool SmUtil
* </pre>
*
* @author loopy_y
* @since 2022/5/15
*/
public class Main{
public static void main(String[] args) {
test1();
test2();
test3();
test4();
test5();
test6();
}
public static void test1() {
System.out.println("======== SM2使用随机生成的密钥对加密或解密,开始 ========");
String text = "SM2使用随机生成的密钥对加密或解密";
SM2 sm2 = SmUtil.sm2();
// 公钥加密,私钥解密
String encryptStr = sm2.encryptBcd(text, KeyType.PublicKey);
System.out.println("密文:" + encryptStr);
String decryptStr = StrUtil.utf8Str(sm2.decryptFromBcd(encryptStr, KeyType.PrivateKey));
System.out.println("明文:" + decryptStr);
System.out.println("======== SM2使用随机生成的密钥对加密或解密,结束 ========");
}
public static void test2() {
System.out.println("======== SM2使用自定义密钥对加密或解密,开始 ========");
String text = "SM2使用自定义密钥对加密或解密";
KeyPair pair = SecureUtil.generateKeyPair("SM2");
byte[] privateKey = pair.getPrivate().getEncoded();
System.out.println("私钥:"+ Base64.encodeBase64String(privateKey));
byte[] publicKey = pair.getPublic().getEncoded();
System.out.println("公钥:"+ Base64.encodeBase64String(publicKey));
SM2 sm2 = SmUtil.sm2(privateKey, publicKey);
// 公钥加密,私钥解密
String encryptStr = sm2.encryptBcd(text, KeyType.PublicKey);
System.out.println("密文:" + encryptStr);
String decryptStr = StrUtil.utf8Str(sm2.decryptFromBcd(encryptStr, KeyType.PrivateKey));
System.out.println("明文:" + decryptStr);
System.out.println("======== SM2使用随机生成的密钥对加密或解密,结束 ========");
}
public static void test3() {
System.out.println("======== SM2签名和验签,开始 ========");
String content = "SM2签名和验签";
final SM2 sm2 = SmUtil.sm2();
String sign = sm2.signHex(HexUtil.encodeHexStr(content));
System.out.println("sign:" + sign);
boolean verify = sm2.verifyHex(HexUtil.encodeHexStr(content), sign);
System.out.println("校验结果为:" + verify);
System.out.println("======== SM2签名和验签,结束 ========");
}
public static void test4() {
System.out.println("======== 摘要加密算法SM3,开始 ========");
String text = "摘要加密算法SM3";
System.out.println("text:" + text);
String digestHex = SmUtil.sm3(text);
System.out.println("digestHex:" + digestHex);
System.out.println("======== 摘要加密算法SM3,结束 ========");
}
public static void test5() {
System.out.println("======== 对称加密SM4,开始 ========");
String content = "对称加密SM4";
SymmetricCrypto sm4 = SmUtil.sm4();
String encryptHex = sm4.encryptHex(content);
System.out.println("密文:" + encryptHex);
String decryptStr = sm4.decryptStr(encryptHex, CharsetUtil.CHARSET_UTF_8);
System.out.println("明文:" + decryptStr);
System.out.println("======== 对称加密SM4,结束 ========");
}
/***
* 分开的:私钥签名,公钥验签
*/
public static void test6(){
System.out.println("======== 私钥签名公钥验签,开始 ========");
String txt = "私钥签名公钥验签";
String privateKey = "MIGTAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBHkwdwIBAQQgfVNnk3eKogEiEAvYinFGZev31dT4gQqcEAAidzIKhC2gCgYIKoEcz1UBgi2hRANCAATolVEVuON8S9aOpnogLTzXzo0Dx58LMFjex7XPPcPtSmuq1Rh/ZM2qbYdZyzdnca8eCeR+cg+44rb/TyPRlH23";
String publicKey = "MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAE6JVRFbjjfEvWjqZ6IC08186NA8efCzBY3se1zz3D7UprqtUYf2TNqm2HWcs3Z3GvHgnkfnIPuOK2/08j0ZR9tw==";
SM2 sm2Sign = SmUtil.sm2(privateKey, null);
byte[] sign = sm2Sign.sign(txt.getBytes(), null);
System.out.println("sign:" + Base64.encodeBase64String(sign));
SM2 sm2 = SmUtil.sm2(null, publicKey);
boolean verify = sm2.verify(txt.getBytes(), sign);
System.out.print("verify:" + verify);
System.out.println("======== 私钥签名公钥验签,结束 ========");
}
}
pom.xml 需要添加的 依赖
<dependencies>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15to18</artifactId>
<version>1.69</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.5.7</version>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.10</version>
</dependency>
</dependencies>
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通