相关文章推荐
果断的土豆  ·  将Unity ...·  1 年前    · 
< groupId > org.bouncycastle < /groupId > < artifactId > bcprov-jdk15on < /artifactId > < version > 1.6 . 8 < /version > < /dependency >
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.bouncycastle.asn1.gm.GMNamedCurves;
import org.bouncycastle.asn1.x9.X9ECParameters;
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.math.ec.ECPoint;
import org.bouncycastle.util.encoders.Hex;
import javax.crypto.Cipher;
import java.math.BigInteger;
import java.security.InvalidAlgorithmParameterException;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.spec.ECGenParameterSpec;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
 * SM2加密
 * @author hcf
 * @date 2021/9/1 14:31
@Slf4j
public class SM2Utils {
     * SM2 生成公私钥
     * @return 公私钥
    public static Map<String, String> generateKeyPair() {
        Map<String, String> resultMap = new HashMap<>(2);
        try {
            BouncyCastleProvider provider = new BouncyCastleProvider();
            // 获取椭圆曲线相关生成参数规格
            ECGenParameterSpec genParameterSpec = new ECGenParameterSpec("sm2p256v1");
            KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("EC", provider);
            // 使用SM2的算法区域初始化密钥生成器
            keyPairGenerator.initialize(genParameterSpec, new SecureRandom());
            // 生成密钥对
            KeyPair keyPair = keyPairGenerator.generateKeyPair();
            BCECPrivateKey exPrivateKey = (BCECPrivateKey) keyPair.getPrivate();
            BCECPublicKey ecPublicKey = (BCECPublicKey) keyPair.getPublic();
            // 解密密钥
            BigInteger privateKey = exPrivateKey.getD();
            // 加密密钥
            ECPoint publicKey = ecPublicKey.getQ();
            resultMap.put("privateKey", privateKey.toString(16));
            resultMap.put("publicKey", new String(Hex.encode(publicKey.getEncoded(true))));
        } catch (NoSuchAlgorithmException | InvalidAlgorithmParameterException e) {
            log.info("NoSuchAlgorithmException | InvalidAlgorithmParameterException {}", e.getMessage(), e);
        return resultMap;
     * sm2 加密
     * @param publicKey 公钥
     * @param content   内容
     * @return 密文
    public static String encrypt(String publicKey, String content) {
        String contentEncrypt = StringUtils.EMPTY;
        try {
            BouncyCastleProvider provider = new BouncyCastleProvider();
            // 获取SM2相关参数
            X9ECParameters parameters = GMNamedCurves.getByName("sm2p256v1");
            // 椭圆曲线参数规格
            ECParameterSpec ecParameterSpec = new ECParameterSpec(parameters.getCurve(), parameters.getG(), parameters.getN(), parameters.getH());
            // 将公钥HEX字符串转换为椭圆曲线对应的点
            ECPoint ecPoint = parameters.getCurve().decodePoint(Hex.decode(publicKey));
            // 获取椭圆曲线KEY生成器
            KeyFactory keyFactory = KeyFactory.getInstance("EC", provider);
            // 将椭圆曲线点转为公钥KEY对象
            BCECPublicKey bcecPublicKey = (BCECPublicKey) keyFactory.generatePublic(new ECPublicKeySpec(ecPoint, ecParameterSpec));
            // 获取SM2加密器
            Cipher cipher = Cipher.getInstance("SM2", provider);
            // 初始化为加密模式
            cipher.init(Cipher.ENCRYPT_MODE, bcecPublicKey);
            // 加密并编码为base64格式
            contentEncrypt = Base64.getEncoder().encodeToString(cipher.doFinal(content.getBytes()));
        } catch (Exception e) {
            log.info("SM2Utils.encrypt(java.lang.String, java.lang.String) error {}", e.getMessage(), e);
        return contentEncrypt;
     * sm2 加密
     * @param publicKey 公钥
     * @param content   内容
     * @return 密文
    public static String encrypt(String publicKey, byte[] content) {
        return encrypt(publicKey, new String(content));
     * sm2 加密
     * @param privateKey     私钥
     * @param contentDecrypt 密文
     * @return 明文
    public static String decrypt(String privateKey, String contentDecrypt) {
        String content = StringUtils.EMPTY;
        try {
            BouncyCastleProvider provider = new BouncyCastleProvider();
            // 获取SM2相关参数
            X9ECParameters parameters = GMNamedCurves.getByName("sm2p256v1");
            // 椭圆曲线参数规格
            ECParameterSpec ecParameterSpec = new ECParameterSpec(parameters.getCurve(), parameters.getG(), parameters.getN(), parameters.getH());
            // 将私钥HEX字符串转换为X值
            BigInteger bigInteger = new BigInteger(privateKey, 16);
            // 获取椭圆曲线KEY生成器
            KeyFactory keyFactory = KeyFactory.getInstance("EC", provider);
            // 将X值转为私钥KEY对象
            BCECPrivateKey bcecPrivateKey = (BCECPrivateKey) keyFactory.generatePrivate(new ECPrivateKeySpec(bigInteger, ecParameterSpec));
            // 获取SM2加密器
            Cipher cipher = Cipher.getInstance("SM2", provider);
            // 初始化为加密模式
            cipher.init(Cipher.DECRYPT_MODE, bcecPrivateKey);
            // 解密
            content = new String(cipher.doFinal(Base64.getDecoder().decode(contentDecrypt)));
        } catch (Exception e) {
            log.info("SM2Utils.encrypt(java.lang.String, java.lang.String) error {}", e.getMessage(), e);
        return content;
     * sm2 加密
     * @param privateKey     私钥
     * @param contentDecrypt 密文
     * @return 明文
    public static String decrypt(String privateKey, byte[] contentDecrypt) {
        return decrypt(privateKey, new String(contentDecrypt));
    public static void main(String[] args) {
        String privateKey = "dbd874c60c8c7432052c7f881ae23f5939d841b12a105bb38ab97129ed02f92d";
        String publicKey = "033e5250957110884657948ce04507833731e7f88a18569f57f16b7e2abe3a79ad";
        System.out.println(encrypt(publicKey, "content"));
        String contentDecrypt = "BP4DukeJwLi9Xfp97HZ39GvfAsJ+u+1Rr8zK5TXd+b95YkwDuZnwFpCtSWkvfxfpXP5DmuIbRBQW0JUgcZ7SXbi+vGM9TDD3LNEVIlvQ1Z5Z8TcotgYsryL6J0eSwtdmoVbhdBEehRw=";
        System.out.println(decrypt(privateKey, contentDecrypt));

参考:
https://blog.csdn.net/RisenMyth/article/details/107212156

开箱即用首先引入包&lt;dependency&gt; &lt;groupId&gt;org.bouncycastle&lt;/groupId&gt; &lt;artifactId&gt;bcprov-jdk15on&lt;/artifactId&gt; &lt;version&gt;1.6.8&lt;/version&gt;&lt;/dependency&gt;import lombok.extern.slf4j.Slf4j;import org.apache.commons.lang3 SM2是国家密码管理局于2010年12月17日发布的椭圆曲线公钥密码算法SM2 算法和 RSA 算法都是公钥密码算法SM2 算法是一种更先进安全的算法,在我们国家商用密码体系中被用来替换 RSA 算法。 随着密码技术和计算机技术的发展,目前常用的 1024 位 RSA 算法面临严重的安全威胁,我们国家密码管理部门经过研究,决定采用 SM2 椭圆曲线算法替换RSA算法SM2算法和RSA算法比较 SM2性能更优更安全:密码复杂度高、处理速度快、机器性能消耗更小
最近因为工作需要,项目中需要采用国密加密,最后根据需求采用了SM2加密。这里简单总结一下用法和踩的坑,供分享和交流。 1.依赖引入 后端依赖引入(Maven,pom.xml): <dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcprov-jdk15on</artifactId> <version>1.70&
最近与一个外部公司对接接口,对方要求使用SM2非对称加密对报文进行签名,防止篡改。约定了各个参数和秘钥后,我发现加解密时在本地IDEA和Eclipse上没有问题,但是打完jar包部署到环境上就会报错,报错内容如下: java.security.spec.InvalidKeySpecException: encoded key spec not recognised at org.bouncycastle.jcajce.provider.asymmetric.util.BaseKeyFactoryS...
1、为什么要使用BouncyCastle? 我们平常都使用jdk自带的加密包对数据进行加密,加密方式也都是使用的默认的,如果我们想选择别的加密方式,发现会报错,比如如下代码: Cipher cipher = Cipher.getInstance("AES/ECB/PKCS7Padding"); cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySp
国密即国家密码局认定的国产密码算法。常用的主要有SM2,SM3,SM4。 SM2:椭圆曲线公钥密码算法是我国自主设计的公钥密码算法,为非对称加密,基于ECC。该算法已公开。由于该算法基于ECC,故其签名速度与秘钥生成速度都快于RSA。 SM3:消息摘要。可以用MD5作为对比理解。该算法已公开。校验结果为256位。 SM4:对称加密,密钥长度和分组长度均为128位。 由于国际环境(与美国的关系),我们在加密领域也基本切换为国密算法。 在有些项目中,没有使用HTTPS的时候,登录的口令(用户名/密码) <groupId>org.bouncycastle</groupId> <artifactId>bcprov-jdk15on</artifactId> <version>1.60</version> </dependency> <dependency> using Org.BouncyCastle.Asn1.X9; using Org.BouncyCastle.Asn1.GM; using Org.BouncyCastle.Crypto.Parameters; using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Security; 加密后内容 可自行验证是否是你需要的sm2加密算法 私钥:BF1F907B4E0487F798DC80AFD7BC2A6201E8514233002272EA3BE2FC6F797843 公钥:前缀04+x坐标+y坐标 042DBA45E7B03394F603CADAFCDDEC854D3E01A4E9C52CD799B85B1A14BDB970137AE58BA553D79F058604DC1CD4B77DE5408BA3308E767584100C2B6
SM2算法国密算法, 是一种非对称加密算法, 主要用于数字签名和加密。 在Java中,可以使用Bouncy Castle库来实现SM2算法。 下面是一个简单的示例代码,用于生成SM2公钥和私钥,并使用它们进行加密和解密: import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.pqc.m...
国密SM2算法是中国自主研发的非对称加密算法,可以用于数字签名、密钥交换等场景。要用C语言实现国密SM2加密算法,需要掌握C语言的基础知识和加密算法的原理。 具体实现过程包括以下步骤: 1. 密钥生成:使用C语言的随机数生成函数生成一对公私钥对。 2. 明文编码:将明文按照国密SM2算法要求进行编码,可以使用C语言的字符编码转换函数实现。 3. 加密操作:使用C语言的加法、减法、乘法、除法等基本运算实现SM2算法中的椭圆曲线点的加减运算、点的倍乘运算等操作。 4. 密文格式:按照国密SM2算法的要求生成密文格式,可以使用C语言的结构体定义和位运算等操作实现。 5. 密文输出:将生成的密文输出。 需要注意的是,实现国密SM2算法需要处理的数据类型和运算较为复杂,需要掌握一定的数学和编程基础。同时,由于加密算法的安全性对于实际应用非常重要,因此需要谨慎实现和测试,以确保实现的算法具有可靠的安全性和正确性。