国密加密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>
相关推荐
GO兔7 分钟前
开篇:GORM入门——Go语言的ORM王者
开发语言·后端·golang·go
欧阳秦穆18 分钟前
apoc-5.24.0-extended.jar 和 apoc-4.4.0.36-all.jar 啥区别
java·jar
好开心啊没烦恼21 分钟前
Python 数据分析:numpy,抽提,整数数组索引与基本索引扩展(元组传参)。听故事学知识点怎么这么容易?
开发语言·人工智能·python·数据挖掘·数据分析·numpy·pandas
岁忧29 分钟前
(LeetCode 面试经典 150 题 ) 58. 最后一个单词的长度 (字符串)
java·c++·算法·leetcode·面试·go
Java初学者小白33 分钟前
秋招Day14 - Redis - 应用
java·数据库·redis·缓存
代码老y39 分钟前
Spring Boot + 本地部署大模型实现:优化与性能提升
java·spring boot·后端
GodKeyNet43 分钟前
设计模式-桥接模式
java·设计模式·桥接模式
future14121 小时前
C#学习日记
开发语言·学习·c#
guojl2 小时前
Java多任务编排技术
java
丶意冷2 小时前
mybatisPlus分页方言设置错误问题 mybatisPlus对于Oceanbase的Oracle租户分页识别错误
java·数据库·oracle·oceanbase