目录 具体Java代码SM2算法加解密实现Demo: pom依赖引入 : 国家密码管理局于2010年12月17日发布了SM2算法,并要求现有的基于RSA算法的电子认证系统、密钥管理系统、应用系统进升级改造,使用支持国密SM2算法的证
目录
国家密码管理局于2010年12月17日发布了SM2算法,并要求现有的基于RSA算法的电子认证系统、密钥管理系统、应用系统进升级改造,使用支持国密SM2算法的证书。
基于ECC椭圆曲线算法的SM2算法,则普遍采用256位密钥长度,它的单位安全强度相对较高,在工程应用中比较难以实现,破译或求解难度基本上是指数级的。因此,SM2算法可以用较少的计算能力提供比RSA算法更高的安全强度,而所需的密钥长度却远比RSA算法低。
对比项目 | ECC加密算法 | RSA加密算法 |
密钥长度 | 256位 | 2048位 |
CPU占用 | 较少 | 较高 |
内存占用 | 较少 | 较高 |
网络消耗 | 较低 | 较高 |
加密效率 | 较高 | 一般 |
破解难度 | 具有数据特性,破解难度大 | 相对ECC理论上容易些 |
抗攻击性 | 强 | 一般 |
可扩展性 | 强 | 一般 |
兼容范围 | 支持新版浏览器和操作系统,但存在少数不支持平台,例如cPanel | 广泛支持 |
package org.example;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;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); }}
org.bouncycastle bcprov-jdk15to18 1.68
来源地址:https://blog.csdn.net/oh_coding/article/details/129182595
--结束END--
本文标题: 国密SM2: 加解密实现 java代码完整示例
本文链接: https://lsjlt.com/news/383991.html(转载时请注明来源链接)
有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
2024-04-01
2024-04-03
2024-04-03
2024-01-21
2024-01-21
2024-01-21
2024-01-21
2023-12-23
回答
回答
回答
回答
回答
回答
回答
回答
回答
回答
0