1秒KO,被ChatGPT完虐……

2023-03-22 19:46:18 浏览数 (1)

国内还有能打的吗

GPT绝对是出道即巅峰

相较之下

百度文心一言不幸沦为背景板

发布会直接翻车

其实不是百度的问题

毕竟在大语言模型的AI领域

百度已经是最强的一个了

奈何对方太强

无论是投入成本还是效果

差距太大了

当天股票暴跌10%

不过还好后劲缓了过来

第二天涨了16%

投资者体验了一把过山车的感觉

不过东西再好,毕竟在老美手里

在信创自主可控的大环境下

对产品有更多的安全方面的要求

毕竟,科学无国界

但科学家有国界

继续学习密码学

在之前的文章里

我们介绍了密码学的发展和演变

从古代的“阴符”、“阴书”

到现代计算机技术的百花齐放

目前主流的对称、非对称、摘要加密算法

大部分都是国外的标准和算法

随着信创产业的发展

自助可控就成了硬性要求

国内也产生了相应的技术

我们称之为“国密算法”

国密算法

国密由国家密码管理局认定

主要用于商用领域

大部分国密算法都叫做 SM-N 的格式

比如 SM1,SM3等等

还有一些是具有民族历史特点的

比如 ZUC 祖冲之算法等

今天先介绍 SM 算法家族的几个常见示例

SM 1 2 3 4

准备工作

创建一个maven项目

pom.xml 引用hutool和bcprov库

代码语言:javascript复制
    <dependency>
        <groupId>cn.hutool</groupId>
        <artifactId>hutool-all</artifactId>
        <version>5.8.5</version>
    </dependency>
    <dependency>
        <groupId>org.bouncycastle</groupId>
        <artifactId>bcprov-jdk15to18</artifactId>
        <version>1.69</version>
    </dependency>

SM1

SM1对于大部分软件工程师来说都很陌生

因为它属于硬件加密

一般是用在 IC卡,智能芯片,加密机,警务通等领域

它是一种对称算法

对标AES,算法不公开

如果不是从事涉密行业的同学

可能一辈子都接触不到

SM2

SM2是非对称算法的一种

有公钥和私钥

对标国际的RSA

SM2的数学原理基于ECC椭圆曲线密码机制

具体过程很复杂

大家主要需要知道如何使用就行


首先通过工具生成秘钥对

代码语言:javascript复制
public class TestSM2 {
 @Test
 void test() {
  SM2 sm2=SmUtil.sm2();
  System.out.println("PublicKey: " sm2.getPublicKeyBase64());
  System.out.println("PrivateKey: " sm2.getPrivateKeyBase64());
 }
}

输出结果为:

代码语言:javascript复制
    PublicKey: MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAEPLJZNooUGYoWA eBPmIhEr7mspmcy8r8b5xWfqQYvGVCe32rMNR5bITvt7hdbiKjbZu0gRxLmZ6D64toLYharw==
    PrivateKey: MIGTAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBHkwdwIBAQQg585PmCpcH0c6X3GnnrAWyZobwotFG5yVWFvXIw1CUqygCgYIKoEcz1UBgi2hRANCAAQ8slk2ihQZihYD54E YiESvuaymZzLyvxvnFZ pBi8ZUJ7fasw1HlshO 3uF1uIqNtm7SBHEuZnoPri2gtiFqv

这个秘钥对是随机生成的

我们把它存下来

下次使用的时候

直接用两个参数初始化

代码语言:javascript复制
public class TestSM2 {
 private String publicKey="MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAEPLJZNooUGYoWA eBPmIhEr7mspmcy8r8b5xWfqQYvGVCe32rMNR5bITvt7hdbiKjbZu0gRxLmZ6D64toLYharw==";
 private String privateKey="MIGTAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBHkwdwIBAQQg585PmCpcH0c6X3GnnrAWyZobwotFG5yVWFvXIw1CUqygCgYIKoEcz1UBgi2hRANCAAQ8slk2ihQZihYD54E YiESvuaymZzLyvxvnFZ pBi8ZUJ7fasw1HlshO 3uF1uIqNtm7SBHEuZnoPri2gtiFqv";
 @Test
 void test() {
//  SM2 sm2=SmUtil.sm2();
  SM2 sm2 = SmUtil.sm2(privateKey, publicKey);
 }
}

然后演示 公钥加密,私钥解密

代码语言:javascript复制
public class TestSM2 {
 private String publicKey="MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAEPLJZNooUGYoWA eBPmIhEr7mspmcy8r8b5xWfqQYvGVCe32rMNR5bITvt7hdbiKjbZu0gRxLmZ6D64toLYharw==";
 private String privateKey="MIGTAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBHkwdwIBAQQg585PmCpcH0c6X3GnnrAWyZobwotFG5yVWFvXIw1CUqygCgYIKoEcz1UBgi2hRANCAAQ8slk2ihQZihYD54E YiESvuaymZzLyvxvnFZ pBi8ZUJ7fasw1HlshO 3uF1uIqNtm7SBHEuZnoPri2gtiFqv";
 @Test
 void test() {
  SM2 sm2 = SmUtil.sm2(privateKey, publicKey);
  
  String data="小面同学我爱你";
  String secretText=sm2.encryptHex(data, KeyType.PublicKey);
  System.out.println(secretText);
 }
}

输出结果为:

~~ 04e53728b5377786dbb8bf3d2dc3803602855cbaf7d287cc647e2f5ff83cbeb28e6be013fa9010763d59dfae0c76e77dc9826420a1c51f360603a9281c31b71873f2c128e7204177a6b2d5ba4f8691b8328c2746a7dd20b890d706174a0754a629e53d3fe9cb8cee30b2e79db692ea39eab7a4c262fb

~~

这就是加密后的话

然后用私钥解密试试

代码语言:javascript复制
public class TestSM2 {
 private String publicKey="MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAEPLJZNooUGYoWA eBPmIhEr7mspmcy8r8b5xWfqQYvGVCe32rMNR5bITvt7hdbiKjbZu0gRxLmZ6D64toLYharw==";
 private String privateKey="MIGTAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBHkwdwIBAQQg585PmCpcH0c6X3GnnrAWyZobwotFG5yVWFvXIw1CUqygCgYIKoEcz1UBgi2hRANCAAQ8slk2ihQZihYD54E YiESvuaymZzLyvxvnFZ pBi8ZUJ7fasw1HlshO 3uF1uIqNtm7SBHEuZnoPri2gtiFqv";
 @Test
 void test() {
  SM2 sm2 = SmUtil.sm2(privateKey, publicKey);
  
  String secretText="04e53728b5377786dbb8bf3d2dc3803602855cbaf7d287cc647e2f5ff83cbeb28e6be013fa9010763d59dfae0c76e77dc9826420a1c51f360603a9281c31b71873f2c128e7204177a6b2d5ba4f8691b8328c2746a7dd20b890d706174a0754a629e53d3fe9cb8cee30b2e79db692ea39eab7a4c262fb";
  String data=sm2.decryptStr(secretText, KeyType.PrivateKey);
  System.out.println(data);
 }
}

输出结果为:

代码语言:javascript复制
小面同学我爱你

个别场合可能加解密会遇到编码转换问题

建议使用 utf-8 编码转换

用法是 String s = StrUtil.utf8Str(s);


对称加密强调数据的加密与复原

并且公钥可以公开

在信息鉴别和秘钥交换方面用处很大

SM3

SM3是一种摘要算法

类似 MD5、SHA-256等

他具有单向加密的特点

无法逆推

主要用于数字签名、完整性效验、认证等功能

SM3 是在SMA-256基础上改进的一种算法

但复杂度远远提高

在防范碰撞攻击方面更具有优势


SM3使用更加简单

因为根本没有秘钥

代码语言:javascript复制
public class TestSM3 {
 @Test
 void test() {
  String data="小面同学我爱你";
  System.out.println(SmUtil.sm3(data));
 }
}

直接一步就行

输出结果为:

代码语言:javascript复制
c6ff5d9098ab6b4b69a306e54ac6eb0ed90656dd9c8ae02d814cccdf202946a3

这里是采用默认的加密方法

可以选择 “加盐” 提高安全性

调整如下:

代码语言:javascript复制
public class TestSM3 {
 @Test
 void test() {
  String data="小面同学我爱你";
  SM3 sm3 = SmUtil.sm3();
  sm3.setSalt("xiaomian".getBytes());
  String secretText=sm3.digestHex(data);
  System.out.println(secretText);
 }
}

输出结果为:

代码语言:javascript复制
e545d9646cd702e93b654aee70f7b9c59af50dcc888e94bfca52ca13afc3134

加盐的目的是增加干扰因素

摘要算法是不可逆的

通常仅用于验证结果

最常见的例如数字签名、密码加密存储等方面使用

SM4

SM4是一种对称加密算法

对标国外的DES算法

使用一个秘钥

可以加密和解密

而且要兼顾复杂度和性能

通常用于内容加密和解密


对称算法只有一个秘钥

首先通过工具生成

代码语言:javascript复制
SM4 sm4 = SmUtil.sm4();
byte[] key=sm4.getSecretKey().getEncoded();

由于工具生成的key是字节,无法阅读和保存

所以我们通常可以自己建key

长度必须128位,一个char是8位

所以文字的密码必须16个英文字长

代码语言:javascript复制
String key="ILoveXiaoMian456";
SM4 sm4 = SmUtil.sm4(key.getBytes());

加密:

代码语言:javascript复制
public class TestSM4 {
 @Test
 void test() {
  String key="ILoveXiaoMian456";
  SM4 sm4 = SmUtil.sm4(key.getBytes());
  
  String data="我爱小面,小面爱我";
  System.out.println(sm4.encryptHex(data));
 }
}

加密成功,输出结果为:

代码语言:javascript复制
382eeef6fd65b154f1f157eadd78c840a5fe1a460aeb478598b3ed2ae137e4a5

解密:

代码语言:javascript复制
public class TestSM4 {
 @Test
 void test() {
  String key="ILoveXiaoMian456";
  SM4 sm4 = SmUtil.sm4(key.getBytes());
  
  String secretText="382eeef6fd65b154f1f157eadd78c840a5fe1a460aeb478598b3ed2ae137e4a5";
  System.out.println(sm4.decryptStr(secretText));
 }
}

输出结果为:

代码语言:javascript复制
我爱小面,小面爱我

总结

加密算法多种多样

主要考虑应用场景

除了以上的SM1234

还有 SM7、SM9等等

大家可以自己研究

0 人点赞