java代码实现sm2加解密
时间: 2023-10-29 21:07:56 浏览: 118
可以使用Bouncy Castle等第三方库来实现SM2算法的加解密操作,以下是Java代码示例:
``` java
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.gm.GMObjectIdentifiers;
import org.bouncycastle.asn1.x9.X9ECParameters;
import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
import org.bouncycastle.crypto.generators.ECKeyPairGenerator;
import org.bouncycastle.crypto.params.ECDomainParameters;
import org.bouncycastle.crypto.params.ECKeyGenerationParameters;
import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
import org.bouncycastle.crypto.params.ECPublicKeyParameters;
import org.bouncycastle.crypto.signers.SM2Signer;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.util.encoders.Hex;
import javax.crypto.Cipher;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.Security;
public class SM2Utils {
static {
Security.addProvider(new BouncyCastleProvider());
}
/**
* 生成SM2公私钥对
*
* @return 公私钥对
* @throws Exception
*/
public static AsymmetricCipherKeyPair generateKeyPair() throws Exception {
X9ECParameters ecParams = GMObjectIdentifiers.sm2p256v1;
ECDomainParameters ecDomainParameters = new ECDomainParameters(ecParams.getCurve(), ecParams.getG(),
ecParams.getN());
ECKeyPairGenerator keyPairGenerator = new ECKeyPairGenerator();
ECKeyGenerationParameters generationParameters = new ECKeyGenerationParameters(ecDomainParameters, null);
keyPairGenerator.init(generationParameters);
return keyPairGenerator.generateKeyPair();
}
/**
* SM2加密
*
* @param data 要加密的数据
* @param privateKey 私钥
* @param publicKey 公钥
* @return 加密结果,以16进制字符串表示
* @throws Exception
*/
public static String encrypt(byte[] data, ECPrivateKeyParameters privateKey, ECPublicKeyParameters publicKey) throws Exception {
Cipher cipher = Cipher.getInstance("SM2", BouncyCastleProvider.PROVIDER_NAME);
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] encrypted = cipher.doFinal(data);
return Hex.toHexString(encrypted);
}
/**
* SM2解密
*
* @param encrypted 加密的数据,以16进制字符串表示
* @param privateKey 私钥
* @param publicKey 公钥
* @return 解密结果
* @throws Exception
*/
public static byte[] decrypt(String encrypted, ECPrivateKeyParameters privateKey, ECPublicKeyParameters publicKey) throws Exception {
Cipher cipher = Cipher.getInstance("SM2", BouncyCastleProvider.PROVIDER_NAME);
cipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] encryptedBytes = Hex.decode(encrypted);
return cipher.doFinal(encryptedBytes);
}
/**
* SM2签名
*
* @param data 要签名的数据
* @param privateKey 私钥
* @return 签名结果,以16进制字符串表示
* @throws Exception
*/
public static String sign(byte[] data, ECPrivateKeyParameters privateKey) throws Exception {
SM2Signer signer = new SM2Signer();
signer.init(true, privateKey);
signer.update(data, 0, data.length);
byte[] signature = signer.generateSignature();
return Hex.toHexString(signature);
}
/**
* SM2验签
*
* @param data 被签名的数据
* @param signature 签名结果,以16进制字符串表示
* @param publicKey 公钥
* @return 验签结果
* @throws Exception
*/
public static boolean verify(byte[] data, String signature, ECPublicKeyParameters publicKey) throws Exception {
SM2Signer signer = new SM2Signer();
signer.init(false, publicKey);
signer.update(data, 0, data.length);
byte[] signatureBytes = Hex.decode(signature);
return signer.verifySignature(signatureBytes);
}
public static void main(String[] args) throws Exception {
AsymmetricCipherKeyPair keyPair = generateKeyPair();
ECPrivateKeyParameters privateKey = (ECPrivateKeyParameters) keyPair.getPrivate();
ECPublicKeyParameters publicKey = (ECPublicKeyParameters) keyPair.getPublic();
String plaintext = "Hello SM2";
String encryptedText = encrypt(plaintext.getBytes("UTF-8"), privateKey, publicKey);
System.out.println("Encrypted Text: " + encryptedText);
byte[] decryptedBytes = decrypt(encryptedText, privateKey, publicKey);
String decryptedText = new String(decryptedBytes, "UTF-8");
System.out.println("Decrypted Text: " + decryptedText);
String signature = sign(plaintext.getBytes("UTF-8"), privateKey);
System.out.println("Signature: " + signature);
boolean verified = verify(plaintext.getBytes("UTF-8"), signature, publicKey);
System.out.println("Verified: " + verified);
}
}
```
如果您有更具体的实现问题可以再提出来,我会尽力解答。
阅读全文