All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.siashan.toolkit.crypt.asymmetric.SM2 Maven / Gradle / Ivy

There is a newer version: 1.2.5
Show newest version
package com.siashan.toolkit.crypt.asymmetric;

import com.siashan.toolkit.crypt.CryptException;
import com.siashan.toolkit.crypt.EncodeType;
import com.siashan.toolkit.crypt.KeyUtil;
import com.siashan.toolkit.crypt.util.BCUtil;
import com.siashan.toolkit.crypt.util.ECKeyUtil;
import org.bouncycastle.crypto.CipherParameters;
import org.bouncycastle.crypto.Digest;
import org.bouncycastle.crypto.InvalidCipherTextException;
import org.bouncycastle.crypto.digests.SM3Digest;
import org.bouncycastle.crypto.engines.SM2Engine;
import org.bouncycastle.crypto.params.ParametersWithID;
import org.bouncycastle.crypto.params.ParametersWithRandom;
import org.bouncycastle.crypto.signers.DSAEncoding;
import org.bouncycastle.crypto.signers.SM2Signer;
import org.bouncycastle.crypto.signers.StandardDSAEncoding;

/**
 * 国密SM2算法实现,基于BC库
* SM2算法只支持公钥加密,私钥解密
* 参考:https://blog.csdn.net/pridas/article/details/86118774 * * @author siashan * @since 1.0.7 */ public class SM2 { /** * 算法EC */ private static final String ALGORITHM_SM2 = "SM2"; /** * SM2默认曲线 */ public static final String SM2_CURVE_NAME = "sm2p256v1"; // --------------------------------------------------------------------------------- Encrypt /** * 加密,SM2非对称加密的结果由C1,C2,C3三部分组成,其中: * *
     * C1 生成随机数的计算出的椭圆曲线点
     * C2 密文数据
     * C3 SM3的摘要值
     * 
* * @param data 被加密的bytes * @param pubKeyParameters 公钥参数 * @return 加密后的bytes * @throws CryptException 异常 */ public static byte[] encrypt(byte[] data, CipherParameters pubKeyParameters) throws CryptException { final SM2Engine engine = getEngine(); try { engine.init(true, pubKeyParameters); return engine.processBlock(data, 0, data.length); } catch (InvalidCipherTextException e) { throw new CryptException(e); } } /** * 加密,SM2非对称加密的结果由C1,C2,C3三部分组成,其中: * * @param data 被加密的bytes * @param publicKey 公钥参数 * @return 加密后的bytes * @throws CryptException 加密异常 */ public static byte[] encrypt(byte[] data, byte[] publicKey) { return encrypt(data, ECKeyUtil.toSm2PublicParams(publicKey)); } /** * 加密,SM2非对称加密的结果由C1,C2,C3三部分组成,其中: * * @param data 被加密的bytes * @param publicKeyPointX 公钥X * @param publicKeyPointY 公钥Y * @return 加密后的bytes * @throws CryptException 加密异常 */ public static byte[] encrypt(byte[] data, byte[] publicKeyPointX, byte[] publicKeyPointY) { return encrypt(data, BCUtil.toSm2Params(publicKeyPointX, publicKeyPointY)); } /** * 加密,SM2非对称加密的结果由C1,C2,C3三部分组成,其中: * * @param data 被加密的bytes * @param publicKeyPointXHex 公钥X * @param publicKeyPointYHex 公钥Y * @return 加密后的bytes * @throws CryptException 加密异常 */ public static byte[] encrypt(byte[] data, String publicKeyPointXHex, String publicKeyPointYHex) { return encrypt(data, BCUtil.toSm2Params(publicKeyPointXHex, publicKeyPointYHex)); } /** * 加密,SM2非对称加密的结果由C1,C2,C3三部分组成,其中: * * @param data 被加密的bytes * @param publicKey 公钥参数 * @return 加密后的bytes * @throws CryptException 加密异常 */ public static byte[] encrypt(byte[] data, String publicKey) { return encrypt(data, KeyUtil.decodeKey(publicKey, EncodeType.HEX)); } /** * 加密,SM2非对称加密的结果由C1,C2,C3三部分组成,其中: * * @param data 被加密的bytes * @param publicKey 公钥参数 * @return 加密后的bytes * @throws CryptException 加密异常 */ public static byte[] encrypt(byte[] data, String publicKey, EncodeType encodeType) { return encrypt(data, KeyUtil.decodeKey(publicKey, encodeType)); } // --------------------------------------------------------------------------------- Decrypt /** * 解密 * * @param data SM2密文,实际包含三部分:ECC公钥、真正的密文、公钥和原文的SM3-HASH值 * @param privateKeyParameters 私钥参数 * @return 加密后的bytes * @throws CryptException 异常 */ public static byte[] decrypt(byte[] data, CipherParameters privateKeyParameters) throws CryptException { final SM2Engine engine = getEngine(); try { engine.init(false, privateKeyParameters); return engine.processBlock(data, 0, data.length); } catch (InvalidCipherTextException e) { throw new CryptException(e); } } /** * 解密 * * @param data SM2密文,实际包含三部分:ECC公钥、真正的密文、公钥和原文的SM3-HASH值 * @param privateKey 私钥 * @return 解密后的bytes * @throws CryptException 异常 */ public static byte[] decrypt(byte[] data, byte[] privateKey) throws CryptException { return decrypt(data, ECKeyUtil.toSm2PrivateParams(privateKey)); } // --------------------------------------------------------------------------------- Sign and Verify /** * 用私钥对信息生成数字签名 * * @param data 加密数据 * @param privateKey 私钥 * @return 签名 */ public byte[] sign(byte[] data, byte[] privateKey) { return sign(data, privateKey, null); } /** * 用私钥对信息生成数字签名 * * @param data 被签名的数据数据 * @param privateKey 私钥 * @param id 可以为null,若为null,则默认withId为字节数组:"1234567812345678".getBytes() * @return 签名 */ public byte[] sign(byte[] data, byte[] privateKey, byte[] id) { final SM2Signer signer = getSigner(); try { CipherParameters param = new ParametersWithRandom(ECKeyUtil.toSm2PrivateParams(privateKey)); if (id != null) { param = new ParametersWithID(param, id); } signer.init(true, param); signer.update(data, 0, data.length); return signer.generateSignature(); } catch (org.bouncycastle.crypto.CryptoException e) { throw new CryptException(e); } } /** * 用公钥检验数字签名的合法性 * * @param data 签名后的数据 * @param sign 签名 * @param publicKey 公钥 * @return 是否验证通过 */ public boolean verify(byte[] data, byte[] sign,byte[] publicKey) { return verify(data, sign, publicKey,null); } /** * 用公钥检验数字签名的合法性 * * @param data 数据签名后的数据 * @param sign 签名 * @param id 可以为null,若为null,则默认withId为字节数组:"1234567812345678".getBytes() * @return 是否验证通过 */ public boolean verify(byte[] data, byte[] sign,byte[] publicKey, byte[] id) { final SM2Signer signer = getSigner(); CipherParameters param = ECKeyUtil.toSm2PublicParams(publicKey); if (id != null) { param = new ParametersWithID(param, id); } signer.init(false, param); signer.update(data, 0, data.length); return signer.verifySignature(sign); } // ------------------------------------------------------------------------------------------------------------------------- Private method start /** * 获取{@link SM2Engine},此对象为懒加载模式 * * @return {@link SM2Engine} */ private static SM2Engine getEngine() { Digest digest = new SM3Digest(); SM2Engine.Mode mode = SM2Engine.Mode.C1C3C2; return new SM2Engine(digest, mode); } /** * 获取{@link SM2Signer},此对象为懒加载模式 * * @return {@link SM2Signer} */ private static SM2Signer getSigner() { DSAEncoding encoding = StandardDSAEncoding.INSTANCE; Digest digest = new SM3Digest(); return new SM2Signer(encoding, digest); } // ------------------------------------------------------------------------------------------------------------------------- Private method end }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy