background
When the function of request parameter encryption is to be realized, the national secret SM2 algorithm is used, the front end sends a request to the background to obtain the public key, the request is encrypted and sent to the background, and the background uses the corresponding private key to decrypt
solution:
Front end adopts: SM2 encryption js library (sm-crypto)
Back-end use: Hutool tool
Since the current front-end SM2 encryption js library (sm-crypto) uses the Q value of the SM2 public key to be converted into hexadecimal for encryption, when sending the public key to the front end in the background, the Q value of the public key needs to be extracted and converted into Hexadecimal.
The back-end generates a secret key pair and the front-end public key public key Q
/**
* 生成SM2公钥,私钥,公钥Q,私钥D <br/>
* 通常由于js端提供的 SM2代码实现的方案,都是直接使用的私钥的d值和公钥的q值直接进行的加解密,
* 所以后端返回的是从公钥里面提取的q值,以q值做为js端的加密公钥,从私钥提取d值,作为js端的解密私钥
* @author 杨攀
* @date 2021/5/13 16:29
* @param
* @return void
*/
public static void createSm2Key() {
SM2 sm = SmUtil.sm2();
// sm2的加解密时有两种方式即 C1C2C3、 C1C3C2,
sm.setMode(SM2Engine.Mode.C1C3C2);
// 生成私钥
String privateKey = HexUtil.encodeHexStr(sm.getPrivateKey().getEncoded());
LOGGER.info("私钥: {}", privateKey);
// 生成公钥
String publicKey = HexUtil.encodeHexStr(sm.getPublicKey().getEncoded());
LOGGER.info("公钥: {}", publicKey);
// 生成私钥D
String privateKeyD = HexUtil.encodeHexStr(BCUtil.encodeECPrivateKey(sm.getPrivateKey())); // ((BCECPrivateKey) privateKey).getD().toByteArray();
LOGGER.info("私钥D: {}", privateKeyD);
// 生成公钥Q,以q值做为js端的加密公钥
String publicKeyQ = HexUtil.encodeHexStr(((BCECPublicKey) sm.getPublicKey()).getQ().getEncoded(false));
LOGGER.info("公钥Q: {}", publicKeyQ);
}
The previous paragraph is encrypted according to the public key Q
Front-end test code:
data() {
return {
// 请求的 service
service: this.$svc.sys.demo,
// 表单数据
formData: {
content: '',
encContent: '',
decContent: '',
},
// 公钥Q
publicKey:'04be3415fd3a7231fa23e4cfdf6f857b0f3137e75692f7b5011d459afc0cdd7741676dca32ca6489cfe0f0fd43b5e9f9f0f77c7997630ba1142c725178a9181558',
// 私钥D (测试才放前端)
privateKey: '74b24bfa8a55127c0fcbe87d7a112e398fd291fd72314e1c56e8d575664a1148',
}
},
method:
// 加密
sm2Encrypt() {
const sm2 = require('sm-crypto').sm2
//let keypair = sm2.generateKeyPairHex()
//this.publicKey = keypair.publicKey // 公钥
//this.privateKey = keypair.privateKey // 私钥
const cipherMode = 1 // 1 - C1C3C2,0 - C1C2C3,默认为 1
//let publicKey = "3059301306072a8648ce3d020106082a811ccf5501822d03420004efddac6873492c460eac87b0b12bec1258f181a5093d62bbb622a7192d58c6c7278f45880dfc226bb0b645268e33a3a8de9d12b7397e05ab729fb35ead70dded";
let encContent = sm2.doEncrypt(this.formData.content, this.publicKey, cipherMode) // sm2加密
this.formData.encContent = encContent;
},
// 解密
sm2Decrypt() {
const sm2 = require('sm-crypto').sm2
let encryptData = this.formData.encContent;
const cipherMode = 1 // 1 - C1C3C2,0 - C1C2C3,默认为 1
let decryptData = sm2.doDecrypt(encryptData, this.privateKey, cipherMode) // 解密结果sm2
this.formData.decContent = decryptData;
},
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。