目录
1. 前言
在安全通信和数据保护中,密码算法至关重要。SM2是中国国家密码管理局发布的椭圆曲线公钥密码算法,广泛应用于金融、政府等领域。本文将介绍如何在Java和Vue的前后端实现SM2 API接口加密。
2. 国密SM2简介
SM2算法是一种基于椭圆曲线的公钥密码算法,主要用于数字签名、数据加密和密钥交换。相比传统的RSA算法,SM2具有更高的安全性和效率。
3. 前期准备
在开始实现之前,需要准备以下开发环境和工具:
- JDK 8+
- Maven或Gradle
- Vue CLI 4+
- npm或yarn
4. 后端实现(Java)
4.1 引入依赖
在后端项目的pom.xml
中添加国密算法相关的依赖。
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.68</version>
</dependency>
4.2 SM2加密解密工具类
创建一个工具类,用于SM2的加密和解密操作。
import org.bouncycastle.asn1.gm.GMNamedCurves;
import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
import org.bouncycastle.crypto.generators.ECKeyPairGenerator;
import org.bouncycastle.crypto.params.*;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.util.encoders.Hex;
import javax.crypto.Cipher;
import java.security.*;
import java.security.spec.ECGenParameterSpec;
public class SM2Utils {
static {
Security.addProvider(new BouncyCastleProvider());
}
public static KeyPair generateKeyPair() throws NoSuchAlgorithmException, NoSuchProviderException, InvalidAlgorithmParameterException {
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("EC", "BC");
keyPairGenerator.initialize(new ECGenParameterSpec("sm2p256v1"), new SecureRandom());
return keyPairGenerator.generateKeyPair();
}
public static String encrypt(String plainText, PublicKey publicKey) throws Exception {
Cipher cipher = Cipher.getInstance("SM2", "BC");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] encryptedData = cipher.doFinal(plainText.getBytes());
return Hex.toHexString(encryptedData);
}
public static String decrypt(String cipherText, PrivateKey privateKey) throws Exception {
Cipher cipher = Cipher.getInstance("SM2", "BC");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] decryptedData = cipher.doFinal(Hex.decode(cipherText));
return new String(decryptedData);
}
}
4.3 示例接口
创建一个简单的REST接口,演示SM2加密和解密操作。
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/api/sm2")
public class SM2Controller {
private final KeyPair keyPair;
public SM2Controller() throws Exception {
this.keyPair = SM2Utils.generateKeyPair();
}
@PostMapping("/encrypt")
public String encrypt(@RequestBody String plainText) throws Exception {
return SM2Utils.encrypt(plainText, keyPair.getPublic());
}
@PostMapping("/decrypt")
public String decrypt(@RequestBody String cipherText) throws Exception {
return SM2Utils.decrypt(cipherText, keyPair.getPrivate());
}
}
5. 前端实现(Vue)
5.1 引入依赖
在前端项目中安装国密算法相关的依赖。
npm install @libit/crypto
5.2 SM2加密解密工具类
创建一个工具类,用于SM2的加密和解密操作。
import { sm2 } from '@libit/crypto';
export default {
generateKeyPair() {
const keypair = sm2.generateKeyPair();
return {
publicKey: keypair.publicKey,
privateKey: keypair.privateKey,
};
},
encrypt(plainText, publicKey) {
return sm2.encrypt(plainText, publicKey);
},
decrypt(cipherText, privateKey) {
return sm2.decrypt(cipherText, privateKey);
},
};
5.3 调用示例
在Vue组件中调用SM2加密和解密操作。
<template>
<div>
<h1>SM2 加密解密示例</h1>
<input v-model="plainText" placeholder="输入明文" />
<button @click="encryptText">加密</button>
<p>密文:{{ cipherText }}</p>
<button @click="decryptText">解密</button>
<p>解密结果:{{ decryptedText }}</p>
</div>
</template>
<script>
import SM2Utils from './SM2Utils';
import axios from 'axios';
export default {
data() {
return {
plainText: '',
cipherText: '',
decryptedText: '',
publicKey: '',
privateKey: '',
};
},
created() {
const { publicKey, privateKey } = SM2Utils.generateKeyPair();
this.publicKey = publicKey;
this.privateKey = privateKey;
},
methods: {
async encryptText() {
const encrypted = SM2Utils.encrypt(this.plainText, this.publicKey);
this.cipherText = encrypted;
// 调用后端接口进行加密
const response = await axios.post('/api/sm2/encrypt', this.plainText);
this.cipherText = response.data;
},
async decryptText() {
const decrypted = SM2Utils.decrypt(this.cipherText, this.privateKey);
this.decryptedText = decrypted;
// 调用后端接口进行解密
const response = await axios.post('/api/sm2/decrypt', this.cipherText);
this.decryptedText = response.data;
},
},
};
</script>
<style>
/* 样式可根据需求自定义 */
</style>
6. 总结
通过本文的介绍,我们了解了如何在Java和Vue的前后端实现国密SM2 API接口加密。后端使用Bouncy Castle库进行SM2加密和解密,前端使用@libit/crypto库进行相应的操作。通过示例接口和Vue组件的实现,我们演示了SM2加密和解密的实际应用。