使用 Java 验证 Bouncy Castle 的签名

问题描述 投票:0回答:0

通过使用 OpenSsl,我生成了证书“test.cer”和密钥存储“test.p12”

然后证书创建:

    Security.addProvider(new BouncyCastleProvider());
    CertificateFactory certFactory = CertificateFactory.getInstance("X.509", "BC");

    X509Certificate certificate = (X509Certificate) certFactory
            .generateCertificate(new FileInputStream("test.cer"));

读取源文件并生成私钥:

        byte[] fileContent = Files.readAllBytes(new File("source.txt").toPath());
        char[] keystorePassword = "password".toCharArray();
        char[] keyPassword = "password".toCharArray();
        KeyStore keystore = KeyStore.getInstance("PKCS12");
        keystore.load(new FileInputStream("test.p12"), keystorePassword);
        PrivateKey privateKey = (PrivateKey) keystore.getKey("archive", keyPassword);

并签名:

    byte[] signedMessage = null;
    List<X509Certificate> certList = new ArrayList<X509Certificate>();
    CMSTypedData cmsData = new CMSProcessableByteArray(data);
    certList.add(signingCertificate);
    Store certs = new JcaCertStore(certList);
    CMSSignedDataGenerator cmsGenerator = new CMSSignedDataGenerator();
    ContentSigner contentSigner
            = new JcaContentSignerBuilder("SHA256withRSA").build(signingKey);
    cmsGenerator.addSignerInfoGenerator(new JcaSignerInfoGeneratorBuilder(
            new JcaDigestCalculatorProviderBuilder().setProvider("BC")
                    .build()).build(contentSigner, signingCertificate));
    cmsGenerator.addCertificates(certs);
    CMSSignedData cms = cmsGenerator.generate(cmsData, true);
    byte[] signedMessage = cms.getEncoded();

signedMessage 我写入扩展名为 .p7s 的文件:

    File targetFile = new File(Paths.get(fileDir).getParent().toString(), "/" + "signed.p7s");
    targetFile.createNewFile();
    Files.write(Paths.get(targetFile.getAbsolutePath()), signedMessage);

然后,当我尝试验证签名时,我收到错误结果。验证是这样实现的:

   byte[] signedData = Files.readAllBytes(new File("signed.p7s").toPath());
    ByteArrayInputStream bIn = new ByteArrayInputStream(signedData);
    ASN1InputStream aIn = new ASN1InputStream(bIn);
    CMSSignedData s = new CMSSignedData(ContentInfo.getInstance(aIn.readObject()));
    aIn.close();
    bIn.close();
    Store certs = s.getCertificates();
    SignerInformationStore signers = s.getSignerInfos();
    Collection<SignerInformation> c = signers.getSigners();
    SignerInformation signer = c.iterator().next();
    Collection<X509CertificateHolder> certCollection = certs.getMatches(signer.getSID());
    Iterator<X509CertificateHolder> certIt = certCollection.iterator();
    X509CertificateHolder certHolder = certIt.next();
    boolean verifResult = signer.verify(newJcaSimpleSignerInfoVerifierBuilder().build(certHolder));

在{JAVA_HOME}/lib/security中我初步提取了local_policy.jar

java digital-signature bouncycastle
© www.soinside.com 2019 - 2024. All rights reserved.