# 前言
SM2 是国家密码管理局于 2010 年 12 月 17 日发布的椭圆曲线公钥密码算法。
SM2 算法和 RSA 算法都是公钥密码算法,SM2 算法是一种更先进安全的算法,在我们国家商用密码体系中被用来替换 RSA 算法。
随着密码技术和计算机技术的发展,目前常用的 1024 位 RSA 算法面临严重的安全威胁,我们国家密码管理部门经过研究,决定采用 SM2 椭圆曲线算法替换 RSA 算法。
# SM2 算法和 RSA 算法比较
SM2 性能更优更安全:密码复杂度高、处理速度快、机器性能消耗更小
详细参考: https://www.ecaa.org.cn/667.html
# 后端代码实现
# 添加 sm2 依赖
| <dependency> |
| <groupId>com.antherd</groupId> |
| <artifactId>sm-crypto</artifactId> |
| <version>0.3.2</version> |
| </dependency> |
# 获取密钥对
| @Test |
| public void testSM2(){ |
| |
| Keypair keypair = Sm2.generateKeyPairHex(); |
| String privateKey = keypair.getPrivateKey(); |
| String publicKey = keypair.getPublicKey(); |
| |
| System.out.println(privateKey); |
| System.out.println(publicKey); |
| |
| System.out.println("========================"); |
| } |
# 使用公私钥进行加解密
| @Test |
| public void testSM2(){ |
| |
| Keypair keypair = Sm2.generateKeyPairHex(); |
| String privateKey = keypair.getPrivateKey(); |
| String publicKey = keypair.getPublicKey(); |
| |
| System.out.println(privateKey); |
| System.out.println(publicKey); |
| |
| System.out.println("========================"); |
| |
| |
| |
| final String doEncrypt = Sm2.doEncrypt("https://softleadergy.github.io/", publicKey); |
| System.out.println("加密: \n" + doEncrypt); |
| |
| final String s = Sm2.doDecrypt(doEncrypt, privateKey); |
| System.out.println("解密:\n" + s); |
| } |
# 前端代码实现 - vue
# 安装依赖
| npm install --save sm-crypto |
# 获取密钥对
| const sm2 = require('sm-crypto').sm2 |
| let keypair = sm2.generateKeyPairHex() |
| publicKey = keypair.publicKey |
| privateKey = keypair.privateKey |
| |
| |
| |
| let keypair2 = sm2.generateKeyPairHex('123123123123123') |
| let keypair3 = sm2.generateKeyPairHex(256, SecureRandom) |
| let verifyResult = sm2.verifyPublicKey(publicKey) |
# 加密解密
| |
| |
| const privateKey = 'a7a9846bbb015f8192bae355be4013d7b7b2bdcf56033b990d58bb5a7541f518' |
| const publicKey = '048ff6380b4db5c9fc9d80fc5e30bde049c12222c56b9085aa1f1c0b53cabd09e72dc5690110e5b57fc3ff88111d0d161723bcb6365c33cef70d3dbbdf32c7038f' |
| |
| |
| const sm2 = require('sm-crypto').sm2 |
| const cipherMode = 1 |
| let encryptData = sm2.doEncrypt(msgString, publicKey, cipherMode) |
| let decryptData = sm2.doDecrypt(encryptData, privateKey, cipherMode) |
| |
| |
| |
# 最终封装
| |
| * 前端加密 |
| * @param text |
| * @returns {*} |
| */ |
| export function encrypt(text) { |
| return sm2.doEncrypt(text, publicKey, 1) |
| } |
| |
| |
| * 前端解密 |
| * @param text |
| * @returns {*} |
| */ |
| export function decrypt(text) { |
| return sm2.doDecrypt(text, privateKey, 1) |
| } |
# 签名验签
# 示例
| @Test |
| public void test(){ |
| |
| Keypair keypair = Sm2.generateKeyPairHex(); |
| String privateKey = keypair.getPrivateKey(); |
| String publicKey = keypair.getPublicKey(); |
| |
| String msg = "https://softleadergy.github.io/"; |
| String encrypt = Sm2.doEncrypt(msg, publicKey); |
| System.out.println("使用公钥加密密文为:"+ encrypt); |
| String decrypt = Sm2.doDecrypt(encrypt, privateKey); |
| System.out.println("使用私钥解密明文为:"+ decrypt); |
| |
| |
| String sigValueHex = Sm2.doSignature(msg, privateKey); |
| System.out.println("使用私钥签名结果为:"+ sigValueHex); |
| boolean verifyResult = Sm2.doVerifySignature(msg, sigValueHex, publicKey); |
| System.out.println("使用公钥验签结果为:"+ verifyResult); |
| } |
# 输出
| 使用公钥加密密文为:89bd07ef376bdc732f2d6430b64a144df14ce7f50fe6aea2d217b79dac1fcf4a950922ed7046a92702aa2f132504b19e8f35449f01a4dcbfb4d8a845e396d27d073b12cc89bb9db8d7bdd88e404be6d2b3d46527cc788012b210633500a3d7f00a7dc9d64d0a78a49ff58be351b03abe2d4cc30abbc5e2ec6fb297f10fa586 |
| 使用私钥解密明文为:https://softleadergy.github.io/ |
| 使用私钥签名结果为:5eeacc471fe227f5679f94e7029ac1c0105420dbea0d8a6532ed03325207f8c191559f191edf05858d787bd3e1de331d179d93ae99dd4c9033a93295054fb5b8 |
| 使用公钥验签结果为:true |
签名验签、获取椭圆曲线点
详细请了解:https://github.com/JuneAndGreen/sm-crypto#readme