国密Sm2 Java+js配合使用

Java端工具类:



import java.math.BigInteger;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Base64;
import org.bouncycastle.asn1.gm.GMNamedCurves;
import org.bouncycastle.asn1.x9.X9ECParameters;
import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
import org.bouncycastle.crypto.InvalidCipherTextException;
import org.bouncycastle.crypto.engines.SM2Engine;
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.math.ec.ECPoint;
import org.bouncycastle.util.encoders.Hex;

/**
 * 
 * @类名称 Sm2Utils.java
 * @类描述 
国密sm2工具类-适用于 js+java后端交互使用
* @作者 yw [email protected] * @创建时间 2021年4月13日 下午1:52:56 * @版本 5.0.0 * * @修改记录 *
 *     版本                       修改人 		修改日期 		 修改内容描述
 *     ----------------------------------------------
 *     5.0.0 	yw 	2021年4月13日             
 *     ----------------------------------------------
 * 
*/ public class Sm2Utils { //流程 通过后台代码生产公私钥对,公钥提供给js端用于数据加密,私钥用于js端传来的密文串解密 private static ECDomainParameters domainParameters = null; private static final String privateKey = "80cfeb110007a9a11295b9289c4b889063f35fe66e54d53fdbb5b8aa335d665a";//生成的私钥 用来解密 /** * 获取椭圆曲线 */ static { //生成密钥对 X9ECParameters sm2ECParameters = GMNamedCurves.getByName("sm2p256v1"); domainParameters = new ECDomainParameters(sm2ECParameters.getCurve(), sm2ECParameters.getG(), sm2ECParameters.getN()); } public static void main(String args[]) { String text = "04be17bf6fe47da1f34a01ad0ff67901241b72d103e998f2f7cc78a004703bdfb8d2c6e3939f4f708f3a57d872d58ec5c41bbe5976666bcb01acea43f5a1c68a62cc117c24821d17c3023035641894d7c978a5521f8dc6798515550c73071f9703602e0ee490157729b648c1cc3eb929c1a0501e12a216d42461117402"; verification(text); } /** * * @方法名称 genPUPRkey * @功能描述
生成公私钥对 公钥给别人拿去加密传输数据,私钥留个自己用来解密
* @作者 yw * @创建时间 2021年4月13日 下午1:57:07 * @throws NoSuchAlgorithmException */ public static void genPUPRkey() throws NoSuchAlgorithmException { //生成密钥对 ECKeyPairGenerator keyPairGenerator = new ECKeyPairGenerator(); keyPairGenerator.init(new ECKeyGenerationParameters(domainParameters, SecureRandom.getInstance("SHA1PRNG"))); AsymmetricCipherKeyPair asymmetricCipherKeyPair = keyPairGenerator.generateKeyPair(); //私钥,16进制格式,自己保存,格式如80cfeb110007a9a11295b9289c4b889063f35fe66e54d53fdbb5b8aa335d665a BigInteger privatekey = ((ECPrivateKeyParameters) asymmetricCipherKeyPair.getPrivate()).getD(); String privateKeyHex = privatekey.toString(16); System.out.println("私钥:" + privateKeyHex); //公钥,16进制格式,发给前端,格式如0467e8c00b1fc2049aa006e75a7216eaf1fb42347b664ea63897917f1281427fa22254d39a3f5fd38e6773edc5eddc074dae27bfbe82d13094bfcbe6b344e89ee9 ECPoint ecPoint = ((ECPublicKeyParameters) asymmetricCipherKeyPair.getPublic()).getQ(); String publicKeyHex = Hex.toHexString(ecPoint.getEncoded(false)); System.out.println("公钥:" + publicKeyHex); } /** * 解密 * @方法名称 decrypt * @功能描述

	 * @作者    yw
	 * @创建时间 2021年4月13日 下午2:09:59
	 * @param ciphertext
	 * @param privatekey
	 * @throws InvalidCipherTextException
	 */
	public static String decrypt(String ciphertext, String privatekey) throws InvalidCipherTextException {
		String cipherData = ciphertext;//JS加密产生的密文
		byte[] cipherDataByte = Hex.decode(cipherData);//格式转换
		 
		BigInteger privateKeyD = new BigInteger(privatekey, 16);//私钥Hex,还原私钥
		ECPrivateKeyParameters privateKeyParameters = new ECPrivateKeyParameters(privateKeyD, domainParameters);
		 
		//用私钥解密
		SM2Engine sm2Engine = new SM2Engine();
		sm2Engine.init(false, privateKeyParameters);
		 
		//processBlock得到Base64格式,记得解码
		byte[] arrayOfBytes = Base64.getDecoder().decode(sm2Engine.processBlock(cipherDataByte, 0, cipherDataByte.length));
		 
		//得到明文:SM2 Encryption Test
		String mtext = new String(arrayOfBytes);
		System.out.println(mtext);
		return mtext;
	}

	
	/**
	 * 
	 * @方法名称 verification
	 * @功能描述 
js的密文校验
* @作者 yw * @创建时间 2021年4月13日 下午2:13:07 * @param ciphertext * @return */ public static String verification(String ciphertext) { String mtext = "";//明文 try { mtext = decrypt(ciphertext, privateKey); System.out.println("mtext:" + mtext); } catch (InvalidCipherTextException e) { e.printStackTrace(); } return mtext ; } }

前端js部分,请参考项目(感谢大佬):

https://github.com/Saberization/SM2

 

你可能感兴趣的:(算法,密码学,Sm2,国密sm2)