国密p7验签,sm3withsm2

我想咨询下java实现国密p7软验签,使用sm3withsm2,只需要验签,需要从签名值里解析出证书验签,可用的内容只有原文和签名值
原文:123456
签名值:MIIDJgYKKoEcz1UGAQQCAqCCAxYwggMSAgEBMQwwCgYIKoEcz1UBgxEwDAYKKoEcz1UGAQQCAaCCAkowggJGMIIB7KADAgECAgV6kZ2zajAKBggqgRzPVQGDdTAvMQswCQYDVQQGEwJjbjEMMAoGA1UECgwDYm9jMRIwEAYDVQQDDAlnbXN1YmNhMDEwHhcNMjIwMzMwMDMxNjIxWhcNMjQxMjI0MDMxNjIxWjB4MQswCQYDVQQGEwJDTjEWMBQGA1UECgwNQk9DIFNNMiBPQ0EzMTERMA8GA1UECwwIUEJQU1RFU1QxGTAXBgNVBAsMEE9yZ2FuaXphdGlvbmFsLTIxIzAhBgNVBAMMGjA0N0Bib2N0ZXN0c20yQFAyMDIyMDMyOUAxMFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAEaPWq1BLLJnsQbKfYVWIX3odW8QU8SlOdPIFgmj5eotqGuF39HLtKL2BnDte6zK0KStGHGDG+dysHCUEofkebd6OBqzCBqDAfBgNVHSMEGDAWgBTwazjBPiVRhWlDe9+pNmz3Fw5YfDAJBgNVHRMEAjAAMEsGA1UdHwREMEIwQKA+oDykOjA4MQ0wCwYDVQQDDARjcmwxMQwwCgYDVQQLDANjcmwxDDAKBgNVBAoMA2JvYzELMAkGA1UEBhMCY24wDgYDVR0PAQH/BAQDAgbAMB0GA1UdDgQWBBS7dSbEbSg7Q+Jrjuy0mhxyCSujMjAKBggqgRzPVQGDdQNIADBFAiEArbvuZl8jb84DIVFwo4QnE9V8LtSid1lzQ0uZUA13SO0CICHqOC/6lld6I6++uhfwHFXZCVsYhaoJSayfErDitg+ZMYGiMIGfAgEBMDgwLzELMAkGA1UEBhMCY24xDDAKBgNVBAoMA2JvYzESMBAGA1UEAwwJZ21zdWJjYTAxAgV6kZ2zajAKBggqgRzPVQGDETALBgkqgRzPVQGCLQEERzBFAiEAgWjzgPEcWhSoRtzXQjfDdMNgDcGhBR3695N+mzl5hfsCIG8UtHZpaI4o5TQVyEJxsPkwLcDPdC7oftupvZqX4/6v

我本地根据这个博客 https://blog.csdn.net/pridas/article/details/86118774 测试是ok的,但是你的这个代码应该是BASE64了,然后你的userId我也不知道是哪个。
测试代码


import org.bouncycastle.util.encoders.Hex;

import java.security.KeyPair;
import java.security.PublicKey;

public class SM2P7Verify {

    public static void main(String[] args) throws Exception {
        String s = "123456";
        byte[] userId = "1234567812345678".getBytes();
        KeyPair keyPair = GmUtil.generateKeyPair();
        PublicKey aPublic = keyPair.getPublic();
        byte[] bytes = GmUtil.signSm3WithSm2(s.getBytes(), userId,  keyPair.getPrivate());
        System.out.println(Hex.toHexString(bytes));
        boolean b = GmUtil.verifySm3WithSm2( s.getBytes(), userId, bytes, aPublic);
        System.out.println(b);
    }

}

测试结果

188dce4b8db74c8b2f940c759fc9ff747b11dc40d0d33be661e276b4567561d066fdf8697b4c4ee702ab44282751603779f370f0759ff388f6fb1003aafa6e2a
true

一般银行会提供验签的调用方法的,或者你可以看看这个,关于java 国密p7验签_基于BC实现的(JAVA版)SM2国密算法签名验签DEMO的资料,看是否对你有帮助:https://blog.csdn.net/weixin_36027743/article/details/115076193

以下答案由GPT-3.5大模型与博主波罗歌共同编写:
java实现国密p7软验签,使用sm3withsm2的步骤如下:

  1. 建立证书工厂,并加载证书:
CertificateFactory cf = CertificateFactory.getInstance("X.509");
FileInputStream fis = new FileInputStream(certPath);
X509Certificate cert = (X509Certificate) cf.generateCertificate(fis);
  1. 获取签名值和待验签原文:
byte[] signature = Base64.decodeBase64(signValue); // 签名值,需要解码
byte[] data = "123456".getBytes(); // 待验签原文
  1. 构造算法实例:
Provider provider = Security.getProvider("BC"); // 注意需要引用BC库
Signature signature = Signature.getInstance("SM3withSM2", provider);
  1. 初始化验签器,并传入证书:
signature.initVerify(cert.getPublicKey());
  1. 传入待验签原文:
signature.update(data);
  1. 执行验签操作,并输出结果(true表示验签成功,false表示验签失败):
boolean verified = signature.verify(signature);
System.out.println("验签结果:" + verified);

完整的验签代码示例:

import java.io.FileInputStream;
import java.security.Provider;
import java.security.Security;
import java.security.Signature;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import org.apache.commons.codec.binary.Base64;

public class SM3withSM2Test {

    public static void main(String[] args) throws Exception {
        
        // 1. 加载证书
        CertificateFactory cf = CertificateFactory.getInstance("X.509");
        FileInputStream fis = new FileInputStream(certPath);
        X509Certificate cert = (X509Certificate) cf.generateCertificate(fis);

        // 2. 获取签名值和待验签原文
        byte[] signature = Base64.decodeBase64(signValue);
        byte[] data = "123456".getBytes();

        // 3. 建立算法实例
        Provider provider = Security.getProvider("BC");
        Signature signature = Signature.getInstance("SM3withSM2", provider);

        // 4. 初始化验签器
        signature.initVerify(cert.getPublicKey());

        // 5. 传入待验签原文
        signature.update(data);

        // 6. 执行验签操作并输出结果
        boolean verified = signature.verify(signature);
        System.out.println("验签结果:" + verified);
    }
}

如果我的回答解决了您的问题,请采纳!