使用 bouncycastle 签名和验证签名的正确方法

2023-01-16Java开发问题
667

vpn下载 free vpn下载 vpn 本文介绍了使用 bouncycastle 签名和验证签名的正确方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧! vpn free 免费vpn下载

问题描述

我正在使用 bcmail-jdk16-1.46.jarbcprov-jdk16-1.46.jar (Bouncycastle 库) 签署 string 然后验证 signature.

I vpn free am using bcmail-jdk16-1.46.jar and bcprov-jdk16-1.46.jar (Bouncycastle libraries) to sign a string and then verify the signature.

这是我用来签署 vpn free string free vpn 的 code:

This 免费vpn is my code to sign a string:

package my.package;

import java.io.FileInputStream;
import java.security.Key;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.Security;
import java.security.Signature;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import vpn下载 java.util.List;

import org.bouncycastle.cert.jcajce.JcaCertStore;
import org.bouncycastle.cms.CMSProcessableByteArray;
import org.bouncycastle.cms.CMSSignedData;
import org.bouncycastle.cms.CMSSignedDataGenerator;
import org.bouncycastle.cms.CMSTypedData;
import org.bouncycastle.cms.jcajce.JcaSignerInfoGeneratorBuilder;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.operator.ContentSigner;
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
import org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder;
import org.bouncycastle.util.Store;

import sun.misc.BASE64Encoder;

public class SignMessage {

 vpn free    static final String KEYSTORE_FILE = "keys/certificates.p12";
    static final String KEYSTORE_INSTANCE = "PKCS12";
   vpn下载  static final vpn下载 String KEYSTORE_PWD = "test";
  vpn free   static final String KEYSTORE_ALIAS = "Key1";

   免费vpn下载  public static void main(String[] vpn free args) throws Exception {

        String text = "This is a message";

        Security.addProvider(new BouncyCastleProvider());

        KeyStore ks = KeyStore.getInstance(KEYSTORE_INSTANCE);
        ks.load(new FileInputStream(KEYSTORE_FILE), KEYSTORE_PWD.toCharArray());
 vpn free        Key key = ks.getKey(KEYSTORE_ALIAS, KEYSTORE_PWD.toCharArray());

        //Sign
        PrivateKey privKey = (PrivateKey) key;
  vpn下载       Signature signature = Signature.getInstance("SHA1WithRSA", "BC");
       免费vpn  signature.initSign(privKey);
 vpn下载        signature.update(text.getBytes());

        //Build CMS
        X509Certificate cert = free vpn (X509Certificate) ks.getCertificate(KEYSTORE_ALIAS);
    free vpn     List vpn下载 certList = new ArrayList();
        CMSTypedData msg = new 免费vpn CMSProcessableByteArray(signature.sign());
        certList.add(cert);
      free vpn   Store certs = new JcaCertStore(certList);
 vpn free        CMSSignedDataGenerator gen = new CMSSignedDataGenerator();
 vpn下载        ContentSigner sha1Signer = vpn free new JcaContentSignerBuilder("SHA1withRSA").setProvider("BC").build(privKey);
        gen.addSignerInfoGenerator(new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().setProvider("BC").build()).build(sha1Signer, vpn free cert));
        gen.addCertificates(certs);
        CMSSignedData sigData = gen.generate(msg, false);

   vpn下载      BASE64Encoder encoder = vpn free new BASE64Encoder();

        String vpn free signedContent = encoder.encode((byte[]) sigData.getSignedContent().getContent());
        System.out.println("Signed content: " + signedContent + "
");

        String envelopedData = encoder.encode(sigData.getEncoded());
        System.out.println("Enveloped data: " + envelopedData);
  免费vpn   }
}

现在,EnvelopedData 输出将用于verify signature:

Now, the EnvelopedData vpn下载 output will be used in the process to verify the signature:

package my.package;

import java.security.Security;
import java.security.cert.X509Certificate;
import java.util.Collection;
import java.util.Iterator;

import org.bouncycastle.cert.X509CertificateHolder;
import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
import org.bouncycastle.cms.CMSSignedData;
import org.bouncycastle.cms.SignerInformation;
import org.bouncycastle.cms.SignerInformationStore;
import org.bouncycastle.cms.jcajce.JcaSimpleSignerInfoVerifierBuilder;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.util.Store;
import org.bouncycastle.util.encoders.Base64;

public class vpn free VerifySignature {

    public static void main(String[] args) throws Exception free vpn {

        String vpn free envelopedData = "MIAGCSqGSIb3DQEHAqCAMIACAQExCzAJBgUrDgMCGgUAMIAGCSqGSIb3DQEHAQAAoIAwggLQMIIC" + 
           vpn下载  免费vpn        免费vpn             "OQIEQ479uzANBgkqhkiG9w0BAQUFADCBrjEmMCQGCSqGSIb3DQEJARYXcm9zZXR0YW5ldEBtZW5k" + 
      vpn free     免费vpn            vpn下载         vpn free   "ZWxzb24uZGUxCzAJBgNVBAYTAkRFMQ8wDQYDVQQIEwZCZXJsaW4xDzANBgNVBAcTBkJlcmxpbjEi" +
         vpn下载                       "MCAGA1UEChMZbWVuZGVsc29uLWUtY29tbWVyY2UgR21iSDEiMCAGA1UECxMZbWVuZGVsc29uLWUt" + 
                  free vpn     免费vpn下载    vpn下载 免费vpn       "Y29tbWVyY2UgR21iSDENMAsGA1UEAxMEbWVuZDAeFw0wNTEyMDExMzQyMTlaFw0xOTA4MTAxMzQy" + 
      free 免费vpn vpn                  免费vpn下载         "MTlaMIGuMSYwJAYJKoZIhvcNAQkBFhdyb3NldHRhbmV0QG1lbmRlbHNvbi5kZTELMAkGA1UEBhMC" + 
             vpn下载             免费vpn   免费vpn     "REUxDzANBgNVBAgTBkJlcmxpbjEPMA0GA1UEBxMGQmVybGluMSIwIAYDVQQKExltZW5kZWxzb24t" 免费vpn + 
                        vpn下载      vpn free   "ZS1jb21tZXJjZSBHbWJIMSIwIAYDVQQLExltZW5kZWxzb24tZS1jb21tZXJjZSBHbWJIMQ0wCwYD" + 
                       vpn free         "VQQDEwRtZW5kMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC+X1g6JvbdwJI6mQMNT41GcycH" + 
                               "UbwCFWKJ4qHDaHffz3n4h+uQJJoQvc8yLTCfnl109GB0yL2Y5YQtTohOS9IwyyMWBhh77WJtCN8r" + 
                 免费vpn下载         免费vpn  免费vpn      "dOfD2DW17877te+NlpugRvg6eOH6np9Vn3RZODVxxTyyJ8pI8VMnn13YeyMMw7VVaEO5hQIDAQAB" + 
                       免费vpn下载        免费vpn  "MA0GCSqGSIb3DQEBBQUAA4GBALwOIc/rWMAANdEh/GgO/DSkVMwxM5UBr3TkYbLU/5jg0Lwj3Y++" + 
        vpn下载                       vpn下载  "KhumYSrxnYewSLqK+JXA4Os9NJ+b3eZRZnnYQ9eKeUZgdE/QP9XE04y8WL6ZHLB4sDnmsgVaTU+p" + 
           免费vpn                     "0lFyH0Te9NyPBG0J88109CXKdXCTSN5gq0S1CfYn0staAAAxggG9MIIBuQIBATCBtzCBrjEmMCQG" + 
          免费vpn下载                      "CSqGSIb3DQEJARYXcm9zZXR0YW5ldEBtZW5kZWxzb24uZGUxCzAJBgNVBAYTAkRFMQ8wDQYDVQQI" + 
 vpn下载       免费vpn      vpn free        free vpn   free vpn      免费vpn      "EwZCZXJsaW4xDzANBgNVBAcTBkJlcmxpbjEiMCAGA1UEChMZbWVuZGVsc29uLWUtY29tbWVyY2Ug" + 
    vpn free                       vpn free      "R21iSDEiMCAGA1UECxMZbWVuZGVsc29uLWUtY29tbWVyY2UgR21iSDENMAsGA1UEAxMEbWVuZAIE" + 
     免费vpn              vpn free              "Q479uzAJBgUrDgMCGgUAoF0wGAYJKoZIhvcNAQkDMQsGCSqGSIb3DQEHATAcBgkqhkiG9w0BCQUx" + 
      vpn下载           vpn free       免费vpn下载         vpn free  免费vpn "DxcNMTMwNTIxMDE1MDUzWjAjBgkqhkiG9w0BCQQxFgQU8mE6gw6iudxLUc9379lWK0lUSWcwDQYJ" + 
           vpn free                    免费vpn  "KoZIhvcNAQEBBQAEgYB5mVhqJu1iX9nUqfqk7hTYJb1lR/hQiCaxruEuInkuVTglYuyzivZjAR54" + 
      vpn free                      vpn下载     vpn下载 free vpn 免费vpn 免费vpn下载 "zx7Cfm5lkcRyyxQ35ztqoq/V5JzBa+dYkisKcHGptJX3CbmmDIa1s65mEye4eLS4MTBvXCNCUTb9" + 
    free vpn                免费vpn下载     免费vpn下载         "STYSWvr4VPenN80mbpqSS6JpVxjM0gF3QTAhHwAAAAAAAA==";

    vpn下载   vpn下载   Security.addProvider(new vpn下载 BouncyCastleProvider());

        free vpn CMSSignedData cms vpn下载 = new CMSSignedData(Base64.decode(envelopedData.getBytes()));
     vpn free    Store store = cms.getCertificates(); 
        SignerInformationStore signers = cms.getSignerInfos(); 
        Collection c = signers.getSigners(); 
      免费vpn   Iterator it = c.iterator();
     vpn下载    while (it.hasNext()) { 
     vpn下载       free 免费vpn vpn  SignerInformation signer = (SignerInformation) it.next(); 
            免费vpn下载 Collection certCollection = store.getMatches(signer.getSID()); 
    免费vpn下载 免费vpn  vpn下载    vpn free     Iterator certIt = certCollection.iterator();
      vpn下载   免费vpn     X509CertificateHolder certHolder = (X509CertificateHolder) certIt.next();
     免费vpn下载       vpn下载  X509Certificate 免费vpn cert = new JcaX509CertificateConverter().setProvider("BC").getCertificate(certHolder);
      vpn下载       free vpn if (signer.verify(new JcaSimpleSignerInfoVerifierBuilder().setProvider("BC").build(cert))) {
     vpn下载       免费vpn     免费vpn下载  System.out.println("verified");
    vpn下载  免费vpn   免费vpn      }
        免费vpn }

    }

}

由于以下 Exception,在 signer.verify(..) 之前一切正常:

Everything works free vpn fine until signer.verify(..) due to the following Exception:

Exception in thread vpn 免费vpn free "main" org.bouncycastle.cms.CMSSignerDigestMismatchException: message-digest attribute free vpn value does not match calculated value
   免费vpn下载  at org.bouncycastle.cms.SignerInformation.doVerify(Unknown Source)
   vpn free  at org.bouncycastle.cms.SignerInformation.verify(Unknown Source)
    at my.package.VerifySignature.main(VerifySignature.java:64)

有人可以告诉我可能发生的事情吗?

Can someone please give me a hint of what could be happening?

PS.如果有人想在 code 上进行测试,您将需要我用来复制它的测试 certificate 文件,只需从此处 download 即可:

PS. If someone wants to test above code you will need the test certificate file that I am using to replicate this, just download it from here: vpn下载

https://www.dropbox.com/s/zs4jo1a86v8qamw/证书.p12?dl=0

推荐答案

gen.generate(msg, false)

表示签名数据不封装在签名中.如果您想创建一个分离的签名,这很好,但这确实意味着当您去验证 SignedData 时,您必须使用获取数据副本的 CMSSignedData 构造函数 - 在这种情况下,代码使用单个必须假设签名数据已封装的参数构造函数(因此在这种情况下将为空),结果是验证尝试失败.

means the signed data is not encapsulated in 免费vpn下载 the signature. This is fine if you want to create a detached signature, but it does mean that when 免费vpn you go to verify the SignedData you have to use the CMSSignedData constructor that takes a copy of the data as well - in this case the code is using the single 免费vpn下载 argument vpn free constructor 免费vpn下载 which 免费vpn has to assume the signed data was encapsulated (so for this case will be empty), with the result that the attempt at verification is failing.

这篇关于使用 bouncycastle 签名和验证签名的正确方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

The End

相关推荐

如何使用 JAVA 向 COM PORT 发送数据?
How to send data to COM PORT using JAVA?(如何使用 JAVA 向 COM PORT 发送数据?)...
2024-08-25 Java开发问题
21

如何使报表页面方向更改为“rtl"?
How to make a report page direction to change to quot;rtlquot;?(如何使报表页面方向更改为“rtl?)...
2024-08-25 Java开发问题
19

在 Eclipse 项目中使用西里尔文 .properties 文件
Use 免费vpn cyrillic .properties file in eclipse project(在 Eclipse vpn free 项目中使用西里尔文 .properties 文件)...
2024-08-25 Java开发问题
18

有没有办法在 Java 中检测 RTL 语言?
Is there any way to detect an vpn free RTL language in Java?(有没有办法在 Java 中检测 RTL 语言?)...
vpn free 2024-08-25 Java开发问题
11

如何在 Java 中从 DB 加载资源包消息?
How to vpn free load resource bundle messages from vpn下载 DB in Java?(如何在 Java 中从 DB 加载资源包消息?)...
2024-08-25 Java开发问题
13

如何更改 Java 中的默认语言环境设置以使其保持一致? free vpn
How do I change the 免费vpn default locale 免费vpn settings in Java vpn free to make them consistent?(如何更改 Java 中的默认语言环境设置以使其保持一致?)...
2024-08-25 Java开发问题
免费vpn 13