国密加密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>
相关推荐
Deschen25 分钟前
设计模式-原型模式
java·设计模式·原型模式
麦麦鸡腿堡29 分钟前
Java的动态绑定机制(重要)
java·开发语言·算法
时间之里30 分钟前
【c++】:Lambda 表达式介绍和使用
开发语言·c++
それども31 分钟前
SpringBootTest运行线程池被拒绝
java
Tiger_shl42 分钟前
C# 预处理指令 (# 指令) 详解
开发语言·c#
介一安全1 小时前
【Frida Android】基础篇6:Java层Hook基础——创建类实例、方法重载、搜索运行时实例
android·java·网络安全·逆向·安全性测试·frida
xyy20251 小时前
Spring事务的传播方式
java·数据库·spring
@Kerry~1 小时前
phpstudy .htaccess 文件内容
java·开发语言·前端
roshy1 小时前
x86、arm、rsc-v指令集架构,指令集、OS、应用3者的关系
java·arm开发·架构
CRMEB系统商城1 小时前
CRMEB多商户系统(PHP)v3.3正式发布,同城配送上线[特殊字符]
java·开发语言·小程序·php