赞
踩
国家密码管理局于2010年12月17日发布了SM2算法,并要求现有的基于RSA算法的电子认证系统、密钥管理系统、应用系统进升级改造,使用支持国密SM2算法的证书。
基于ECC椭圆曲线算法的SM2算法,则普遍采用256位密钥长度,它的单位安全强度相对较高,在工程应用中比较难以实现,破译或求解难度基本上是指数级的。因此,SM2算法可以用较少的计算能力提供比RSA算法更高的安全强度,而所需的密钥长度却远比RSA算法低。
- <dependency>
- <groupId>org.bouncycastle</groupId>
- <artifactId>bcprov-jdk15to18</artifactId>
- <version>1.68</version>
- </dependency>
- package com.xinan.security.sm2;
- import org.bouncycastle.asn1.gm.GMNamedCurves;
- import org.bouncycastle.asn1.x9.X9ECParameters;
- import org.bouncycastle.crypto.engines.SM2Engine;
- import org.bouncycastle.crypto.params.ECDomainParameters;
- import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
- import org.bouncycastle.crypto.params.ECPublicKeyParameters;
- import org.bouncycastle.crypto.params.ParametersWithRandom;
- import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPrivateKey;
- import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPublicKey;
- import org.bouncycastle.jce.provider.BouncyCastleProvider;
- import org.bouncycastle.jce.spec.ECParameterSpec;
- import org.bouncycastle.jce.spec.ECPrivateKeySpec;
- import org.bouncycastle.jce.spec.ECPublicKeySpec;
- import org.bouncycastle.util.encoders.Hex;
-
- import java.math.BigInteger;
- import java.security.*;
- import java.security.spec.ECGenParameterSpec;
- /**
- *SM2算法工具类
- * @version 1.0
- */
- public class SM2Utils {
- public static KeyPair createECKeyPair() {
- final ECGenParameterSpec sm2Spec = new ECGenParameterSpec("sm2p256v1");
-
- // 获取一个椭圆曲线类型的密钥对生成器
- final KeyPairGenerator kpg;
- try {
- kpg = KeyPairGenerator.getInstance("EC", new BouncyCastleProvider());
- kpg.initialize(sm2Spec, new SecureRandom());
-
- return kpg.generateKeyPair();
- } catch (Exception e) {
- e.printStackTrace();
- return null;
- }
- }
-
- public static String encrypt(String publicKeyHex, String data) {
- return encrypt(getECPublicKeyByPublicKeyHex(publicKeyHex), data, 1);
- }
-
- public static String encrypt(BCECPublicKey publicKey, String data, int modeType) {
- //加密模式
- SM2Engine.Mode mode = SM2Engine.Mode.C1C3C2;
- if (modeType != 1) {
- mode = SM2Engine.Mode.C1C2C3;
- }
- ECParameterSpec ecParameterSpec = publicKey.getParameters();
- ECDomainParameters ecDomainParameters = new ECDomainParameters(ecParameterSpec.getCurve(),
- ecParameterSpec.getG(), ecParameterSpec.getN());
- ECPublicKeyParameters ecPublicKeyParameters = new ECPublicKeyParameters(publicKey.getQ(), ecDomainParameters);
-
- SM2Engine sm2Engine = new SM2Engine(mode);
-
- sm2Engine.init(true, new ParametersWithRandom(ecPublicKeyParameters, new SecureRandom()));
- byte[] arrayOfBytes = null;
- try {
- byte[] in = data.getBytes("utf-8");
-
- arrayOfBytes = sm2Engine.processBlock(in, 0, in.length);
- } catch (Exception e) {
- System.out.println("SM2加密时出现异常:" + e.getMessage());
- e.printStackTrace();
- }
- return Hex.toHexString(arrayOfBytes);
- }
-
- public static String decrypt(String privateKeyHex, String cipherData) {
- return decrypt(getBCECPrivateKeyByPrivateKeyHex(privateKeyHex), cipherData, 1);
- }
-
- public static String decrypt(BCECPrivateKey privateKey, String cipherData, int modeType) {
- //解密模式
- SM2Engine.Mode mode = SM2Engine.Mode.C1C3C2;
- if (modeType != 1) {
- mode = SM2Engine.Mode.C1C2C3;
- }
-
- byte[] cipherDataByte = Hex.decode(cipherData);
- ECParameterSpec ecParameterSpec = privateKey.getParameters();
- ECDomainParameters ecDomainParameters = new ECDomainParameters(ecParameterSpec.getCurve(),
- ecParameterSpec.getG(), ecParameterSpec.getN());
- ECPrivateKeyParameters ecPrivateKeyParameters = new ECPrivateKeyParameters(privateKey.getD(),
- ecDomainParameters);
-
- SM2Engine sm2Engine = new SM2Engine(mode);
- sm2Engine.init(false, ecPrivateKeyParameters);
- String result = null;
- try {
- byte[] arrayOfBytes = sm2Engine.processBlock(cipherDataByte, 0, cipherDataByte.length);
- result = new String(arrayOfBytes, "utf-8");
- } catch (Exception e) {
- System.out.println("SM2解密时出现异常" + e.getMessage());
- }
- return result;
- }
-
- private static X9ECParameters x9ECParameters = GMNamedCurves.getByName("sm2p256v1");
-
- private static ECParameterSpec ecDomainParameters = new ECParameterSpec(x9ECParameters.getCurve(), x9ECParameters.getG(), x9ECParameters.getN());
-
- public static BCECPublicKey getECPublicKeyByPublicKeyHex(String pubKeyHex) {
-
- if (pubKeyHex.length() > 128) {
- pubKeyHex = pubKeyHex.substring(pubKeyHex.length() - 128);
- }
- String stringX = pubKeyHex.substring(0, 64);
- String stringY = pubKeyHex.substring(stringX.length());
- BigInteger x = new BigInteger(stringX, 16);
- BigInteger y = new BigInteger(stringY, 16);
-
- ECPublicKeySpec ecPublicKeySpec = new ECPublicKeySpec(x9ECParameters.getCurve().createPoint(x, y), ecDomainParameters);
-
- return new BCECPublicKey("EC", ecPublicKeySpec, BouncyCastleProvider.CONFIGURATION);
- }
-
- public static BCECPrivateKey getBCECPrivateKeyByPrivateKeyHex(String privateKeyHex) {
- BigInteger d = new BigInteger(privateKeyHex, 16);
- ECPrivateKeySpec ecPrivateKeySpec = new ECPrivateKeySpec(d, ecDomainParameters);
- return new BCECPrivateKey("EC", ecPrivateKeySpec, BouncyCastleProvider.CONFIGURATION);
- }
-
- public static void main(String[] args) {
- String publicKeyHex = null;
- String privateKeyHex = null;
- KeyPair keyPair = createECKeyPair();
- PublicKey publicKey = keyPair.getPublic();
- if (publicKey instanceof BCECPublicKey) {
- //获取65字节非压缩缩的十六进制公钥串(0x04)
- publicKeyHex = Hex.toHexString(((BCECPublicKey) publicKey).getQ().getEncoded(false));
- System.out.println("SM2公钥:" + publicKeyHex);
- }
- PrivateKey privateKey = keyPair.getPrivate();
- if (privateKey instanceof BCECPrivateKey) {
- //获取32字节十六进制私钥串
- privateKeyHex = ((BCECPrivateKey) privateKey).getD().toString(16);
- System.out.println("SM2私钥:" + privateKeyHex);
- }
-
- /**
- * 公钥加密
- */
- String data = "=========需要加密的数据=========";
-
- //将十六进制公钥串转换为 BCECPublicKey 公钥对象
- String encryptData = encrypt(publicKeyHex, data);
- System.out.println("加密结果:" + encryptData);
-
- /**
- * 私钥解密
- */
- //将十六进制私钥串转换为 BCECPrivateKey 私钥对象
- data = decrypt(privateKeyHex, encryptData);
- System.out.println("解密结果:" + data);
- }
-
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。