解决sm2算法加密版本冲突——maven-shade

问题描述

        在maven项目中引入新的第三方组件时,组件中的依赖可能会与项目已有组件依赖的jar包(其他组件)发生冲突。

比如引入的bcprov-jdk15on 是1.68,无法覆盖旧版本1.51,导致冲突。

解决方案

使用maven-shade将bcprov-jdk15on -1.68重新打包,mvn install再引入

  • 新建空项目,编辑pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.tt</groupId>
    <artifactId>shade-test</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <dependency>
            <groupId>org.bouncycastle</groupId>
            <artifactId>bcprov-jdk15on</artifactId>
            <version>1.68</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-shade-plugin</artifactId>
                <version>3.2.4</version>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>shade</goal>
                        </goals>
                        <configuration>
                            <filters>
                                <filter>
                                    <artifact>*:*</artifact>
                                    <excludes>
                                        <!--排除文件-->
                                        <exclude>META-INF/*.SF</exclude>
                                    </excludes>
                                </filter>
                            </filters>

                            <relocations>
                                <relocation>
                                    <!--原路径-->
                                    <pattern>org.bouncycastle</pattern>
                                    <!--替换路径-->
                                    <shadedPattern>shade.org.bouncycastle</shadedPattern>
                                </relocation>
                            </relocations>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>


</project>
  • 编写加密工具类
package com.tt;

import org.bouncycastle.asn1.gm.GMNamedCurves;
import org.bouncycastle.asn1.x9.X9ECParameters;
import org.bouncycastle.crypto.CipherParameters;
import org.bouncycastle.crypto.InvalidCipherTextException;
import org.bouncycastle.crypto.digests.SM3Digest;
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.math.ec.ECCurve;
import org.bouncycastle.math.ec.ECPoint;
import org.bouncycastle.util.BigIntegers;
import org.bouncycastle.util.encoders.Hex;

import java.math.BigInteger;


public class Sm2TtUtil {



    /**
     * SM2加密算法
     *
     * @param publicKey 公钥
     * @param data      数据
     * @return
     */
    public static String encrypt(String publicKey, String data) {
        X9ECParameters x9ECParameters = GMNamedCurves.getByName("sm2p256v1");

        ECDomainParameters domainParameters = new ECDomainParameters(x9ECParameters.getCurve(), x9ECParameters.getG(), x9ECParameters.getN(), x9ECParameters.getH());

        ECCurve curve = domainParameters.getCurve();

        byte[] pointEncoded = Hex.decode(publicKey);
        ECPoint point = curve.decodePoint(pointEncoded);
        ECPublicKeyParameters ecPublicKeyParameters = new ECPublicKeyParameters(point, domainParameters);

        CipherParameters pubKeyParameters = new ParametersWithRandom(ecPublicKeyParameters, null);

        SM2Engine engine = new SM2Engine(new SM3Digest(),SM2Engine.Mode.C1C3C2);


        engine.init(true, pubKeyParameters);

        byte[] bytes = data.getBytes();
        byte[] dest = new byte[0];
        try {
            dest = engine.processBlock(bytes, 0, bytes.length);
        } catch (InvalidCipherTextException e) {
            e.printStackTrace();
        }

        return Hex.toHexString(dest);
    }

    /**
     * SM2解密算法
     *
     * @param privateKey 私钥
     * @param cipherData 密文数据
     * @return
     */
    public static String decrypt(String privateKey, String cipherData) {
        byte[] cipherDataByte = Hex.decode(cipherData);

        //获取一条SM2曲线参数
        X9ECParameters sm2ECParameters = GMNamedCurves.getByName("sm2p256v1");
        //构造domain参数
        ECDomainParameters domainParameters = new ECDomainParameters(sm2ECParameters.getCurve(),
                sm2ECParameters.getG(), sm2ECParameters.getN());


        byte[] decode = Hex.decode(privateKey);
        BigInteger bigInteger = BigIntegers.fromUnsignedByteArray(decode);
        ECPrivateKeyParameters privateKeyParameters = new ECPrivateKeyParameters(bigInteger, domainParameters);

        SM2Engine sm2Engine = new SM2Engine(new SM3Digest(),SM2Engine.Mode.C1C3C2);
        sm2Engine.init(false, privateKeyParameters);

        String result = null;
        try {
            byte[] arrayOfBytes = sm2Engine.processBlock(cipherDataByte, 0, cipherDataByte.length);
            return new String(arrayOfBytes);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;

    }


    public static String staticPublicKey = "0408fda0c0f6d1e51289cd5edcef7386a696e1a63659dd4ae3516cfd4d0a5dfaa341ff9c86f2572cae9e1406a036d43b71862e8acf0dbfaeb6216c775038b46d40";
    public static String staticPrivateKey = "2158c2678f7ee7685392ddc31916b8c835a98887040bbf69f76fa4aa0acff42e";

    public static void main(String[] args) {
        String message = "HUSUADOI7OM4URCO";
        //加密
        String resultPublic = encrypt(staticPublicKey,message);
        System.out.println("加密结果:" + resultPublic);
        //解密
        String resultPrivate = decrypt(staticPrivateKey,resultPublic);
        System.out.println("解密结果:" + resultPrivate);
        System.out.println("验证结果:"+message.equals(resultPrivate));
    }

}
  •  重新打包

  • 对比结果

  • 成功引用新包

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
sm2算法是一种国家密码学标准算法,它主要用于椭圆曲线公钥密码体制中的加密和数字签名。sm2算法基于椭圆曲线离散对数问题,具有安全性和高效性的特点。 sm2算法的C语言实现主要括以下几个步骤: 1. 选择椭圆曲线参数:sm2算法使用的是国家标准椭圆曲线参数,可以在标准文档中找到。选择合适的参数,初始化椭圆曲线。 2. 生成密钥对:使用随机数生成器生成一个私钥,并通过椭圆曲线上的点运算得到对应的公钥。 3. 加密过程:假设要加密的明文为M,首先将M转换成点P,再生成一个随机数k。通过点运算得到C1=kG,其中G为基点。然后计算点S=kP,将S的x坐标转换成字节数组,作为SM3算法的输入,得到哈希值H。最后计算C2=M⨁H,C3=k^-1·(hash(kP)+C2)。 4. 解密过程:给定密文C=(C1,C2,C3),首先计算C1的k倍点为kC1,并将kC1的x坐标作为SM3算法的输入,得到哈希值H。然后计算C2=M⨁H,并利用C1的k倍点计算kP。最后计算hash(kP)+C2,乘以C3的k^-1得到明文M。 5. 数字签名过程:给定要签名的消息M和私钥d,首先计算消息的哈希值H。然后生成一个随机数k,并通过点运算得到点R=kG。将R的x坐标转换成字节数组,作为SM3算法的输入,得到哈希值h。计算s=(h+d·r)·⁻¹·k。最后签名为(R,s)。 以上是sm2算法的简要介绍和C语言实现的整体步骤,实现过程中需注意安全性和正确性。具体的C语言代码实现需要详细研究和阅读sm2算法的相关标准文档,理解椭圆曲线运算和密码哈希算法的具体细节,然后按照算法规范进行编码实现。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值