国密加密golang加密,java解密

golang加密:

Go 复制代码
package main

import (
	"crypto/rand"
	"encoding/hex"
	"fmt"
	"github.com/tjfoc/gmsm/sm2"
)


func main() {

// 生成SM2密钥对
	privateKey, err := sm2.GenerateKey(rand.Reader)
	if err != nil {
		panic(err)
	}

	// 打印出私钥D值(注意:实际应用中不应直接打印或暴露私钥)
	fmt.Printf("Private Key D: %x\n", privateKey.D.Bytes())

	// 将公钥转换为04开头的X9.62格式字符串
	pubKeyBytes := append([]byte{0x04}, append(privateKey.X.Bytes(), privateKey.Y.Bytes()...)...)
	pubKeyStr := hex.EncodeToString(pubKeyBytes)
	fmt.Printf("Public Key: %s\n", pubKeyStr)

	// 准备要签名的消息
	message := []byte("Hello World!")

	// 使用私钥对消息进行签名
	signature, err := privateKey.Sign(rand.Reader, message, nil)
	if err != nil {
		panic(err)
	}

	// 打印签名结果(通常会以Base64或Hex编码形式传输)
	sigStr := hex.EncodeToString(signature)
	fmt.Printf("Signature: %s\n", sigStr)
}

java解密:

java 复制代码
import java.security.spec.*;
import java.util.*;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.jce.spec.ECNamedCurveSpec;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

import org.bouncycastle.crypto.params.ECDomainParameters;
import org.bouncycastle.crypto.params.ECPublicKeyParameters;
import org.bouncycastle.crypto.signers.SM2Signer;
import org.bouncycastle.jce.ECNamedCurveTable;
import org.bouncycastle.jce.spec.ECNamedCurveParameterSpec;
import org.bouncycastle.util.encoders.Hex;

import java.math.BigInteger;
import java.security.Security;
import java.security.KeyFactory;
import java.security.PublicKey;

    @Test
    void sm2Test() throws Exception {

        // 假设从Go端接收到的公钥是04开头的X9.62格式字符串
        String pubKeyStr = "046ae10d888e6dfa1bda8987f69fce9cbf2b73afa8b17666593db1edabe224ecbe9214fecac1b576e65614b99cf497e45c017eb41f67cd51a8b0c315061b3028b5"; // 替换为实际接收到的公钥字符串
        byte[] pubKeyBytes = Hex.decode(pubKeyStr.substring(2)); // 去掉前缀"04"

        // 确保公钥字节数组长度为偶数
        if (pubKeyBytes.length % 2 != 0) {
            throw new IllegalArgumentException("Public key length must be even.");
        }

        // 分割为X坐标
        byte[] xCoordBytes = Arrays.copyOfRange(pubKeyBytes, 0, pubKeyBytes.length / 2);

        // 分割为Y坐标
        byte[] yCoordBytes = Arrays.copyOfRange(pubKeyBytes, pubKeyBytes.length / 2, pubKeyBytes.length);


        // 加载SM2曲线参数
        ECNamedCurveParameterSpec sm2Params = ECNamedCurveTable.getParameterSpec("sm2p256v1");

        // 构建ECParameterSpec对象
        ECParameterSpec ecSpec = new ECNamedCurveSpec(
                "sm2p256v1", // 曲线名称
                sm2Params.getCurve(), // 椭圆曲线
                sm2Params.getG(),     // 基点
                sm2Params.getN()      // 阶数
        );

        ECPublicKeySpec pubKeySpec = new ECPublicKeySpec(
                new ECPoint(new BigInteger(1, xCoordBytes),
                        new BigInteger(1, yCoordBytes)),
                ecSpec
        );

        // 获取ECPublicKey实例
        KeyFactory keyFactory = KeyFactory.getInstance("EC", "BC");
        PublicKey publicKey = keyFactory.generatePublic(pubKeySpec);

        // 解码来自Go端的签名
        String sigStr = "304402204c20712bb1088ed7476c24d64518cdce722c2b31ec5639aca9ed30e5676ce6ba02200d57823f08dc009e980ca2db1db9a6ecce2a5c66fefca38bc730c9382ab36580"; // 替换为实际接收到的签名字符串
        byte[] signature = Hex.decode(sigStr);

        // 初始化SM2签名器
        SM2Signer signer = new SM2Signer();
        ECDomainParameters domainParams = new ECDomainParameters(
                sm2Params.getCurve(), // 椭圆曲线
                sm2Params.getG(),     // 基点
                sm2Params.getN()      // 阶数
        );

        // 直接从xCoordBytes和yCoordBytes构建ECPoint对象
        org.bouncycastle.math.ec.ECPoint q = sm2Params.getCurve().createPoint(
                new BigInteger(1, xCoordBytes),
                new BigInteger(1, yCoordBytes)
        );

// 使用ECPoint对象初始化ECPublicKeyParameters
        ECPublicKeyParameters publicKeyParams = new ECPublicKeyParameters(q, domainParams);

// 初始化签名验证器
        signer.init(false, publicKeyParams);

        // 更新签名器
        byte[] message = "Hello World!".getBytes(); // 确保与Go端相同的消息内容
        signer.update(message, 0, message.length);

        // 验证签名
        boolean isValid = signer.verifySignature(signature);
        System.out.println("Signature is valid: " + isValid);
    }


pom.xml依赖:
        <dependency>
            <groupId>org.bouncycastle</groupId>
            <artifactId>bcpkix-jdk15on</artifactId>
            <version>1.70</version>
        </dependency>
        <dependency>
            <groupId>commons-codec</groupId>
            <artifactId>commons-codec</artifactId>
            <version>1.15</version>
        </dependency>
相关推荐
维吉斯蔡6 小时前
【VS Code / Cursor】文件夹右键快捷打开与文件类型自动关联
开发语言·程序人生·学习方法
蓝斯4976 小时前
[原创]《C#高级GDI+实战:从零开发一个流程图》第章:增加贝塞尔曲线,上、下、左、右连接点
java·c#·流程图
前端工作日常6 小时前
我学习到的Java 的 Service 分层:itf 和 impl 到底是什么?
java·后端
都叫我大帅哥7 小时前
Spring @Transactional 注解完全指南
java·spring
Java成神之路-7 小时前
G1 垃圾回收器 :SATB + TAMS核心机制深度解析
java·jvm
前端工作日常7 小时前
我学习到的JIT即时编译与机器码缓存失效
java·后端
带刺的坐椅7 小时前
Solon 的 10 种 HTTP 服务器:改一行依赖,换一个引擎
java·solon·jetty·undertow·mcp-server·htttp
luj_17688 小时前
星火科技助力边远地区防病攻坚
c语言·开发语言·c++·经验分享·算法
always_TT8 小时前
【Python 日志记录:logging 模块入门】
开发语言·python·php
xcLeigh8 小时前
Go入门:变量声明的五种方式详解
java·开发语言·golang