使用 PAdES-LT 级别通过 DSS 对 PDF 进行签名

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

我正在使用 DSS 库使用 PAdES-LT 级别对 PDF 进行签名。我已经尝试过 B 级和 T 级,效果很好。一开始我遇到了 LT 级别的问题,因为它仅使用在线验证器验证为 T,所以我试图找到问题,但没有运气。我使用外部服务器进行哈希签名以及 TSA。

        List<CertificateResponse> certificateResponses = client.getCertificateChain();
        List<Certificate> certificates = new ArrayList<>();
        for (CertificateResponse certificateResponse : certificateResponses) {
            byte[] certificate = Base64.getDecoder().decode(certificateResponse.certificate());
            X509Certificate cert = (X509Certificate) CertificateFactory
                    .getInstance("X.509").generateCertificate(new ByteArrayInputStream(certificate));
            certificates.add(cert);
        }

        List<CertificateToken> certificateTokens = certificates.stream()
                .map(c -> new CertificateToken((X509Certificate) c)).toList();

        CommonCertificateVerifier certificateVerifier = new CommonCertificateVerifier();

        CommonTrustedCertificateSource certificateSource = new CommonTrustedCertificateSource();
        for (CertificateToken certificateToken : certificateTokens) {
            certificateSource.addCertificate(certificateToken);
        }

        OnlineCRLSource onlineCRLSource = new OnlineCRLSource();
        onlineCRLSource.setDataLoader(new CommonsDataLoader());
        certificateVerifier.setCrlSource(onlineCRLSource);

        OnlineOCSPSource onlineOCSPSource = new OnlineOCSPSource();
        onlineOCSPSource.setDataLoader(new OCSPDataLoader());
        onlineOCSPSource.setNonceSource(new SecureRandomNonceSource());
        certificateVerifier.setOcspSource(onlineOCSPSource);

        certificateVerifier.setTrustedCertSources(certificateSource);
        certificateVerifier.setRevocationDataVerifier(RevocationDataVerifier.createDefaultRevocationDataVerifier());
        certificateVerifier.setCheckRevocationForUntrustedChains(true);

        PAdESService service = new PAdESService(certificateVerifier);
        service.setTspSource(tspSource);

        DSSDocument toSignDocument = new InMemoryDocument(pdf);
        PAdESSignatureParameters parameters = new PAdESSignatureParameters();
        parameters.setDigestAlgorithm(DigestAlgorithm.SHA256);
        parameters.setSignatureLevel(SignatureLevel.PAdES_BASELINE_LT);
        parameters.setGenerateTBSWithoutCertificate(false);
        parameters.setSigningCertificate(certificateTokens.get(0));
        parameters.setCertificateChain(certificateTokens);
        parameters.setCheckCertificateRevocation(true);

        ToBeSigned dataToSign = service.getDataToSign(toSignDocument, parameters);

        final SigningRequest signingRequest = new SigningRequest();
        signingRequest.setHashSignatures(List.of(new HashSignature("id-1", Hasher.hash(dataToSign.getBytes()).bytes())));
        final SigningResult signingResult = client.sign(signingRequest);

        SignatureValue signatureValue = new SignatureValue(SignatureAlgorithm.RSA_SHA256,
                Base64.getDecoder().decode(signingResult.signature()));

        DSSDocument signedDocument = service.signDocument(toSignDocument, parameters, signatureValue);

我收到以下错误:

2023-08-24T17:43:04.200+02:00  WARN 38245 --- [           main] e.e.e.d.s.x.SignatureIntegrityValidator  : Determining signing certificate from certificate candidates list failed: [Best candidate validation failed : Unable to validate CMS Signature : can't create content verifier: exception on setup: java.security.InvalidKeyException: Supplied key (null) is not a RSAPublicKey instance]
eu.europa.esig.dss.exception.IllegalInputException: Signing certificate token was not found! Unable to verify its validity range. Use method setSignWithNotYetValidCertificate(true) to skip the check.
    at eu.europa.esig.dss.signature.SignatureRequirementsChecker.assertSigningCertificateIsYetValid(SignatureRequirementsChecker.java:104)
    at eu.europa.esig.dss.signature.SignatureRequirementsChecker.assertSigningCertificateIsValid(SignatureRequirementsChecker.java:88)
    at eu.europa.esig.dss.cades.signature.CAdESLevelBaselineT.extendSignerInformation(CAdESLevelBaselineT.java:99)
    at eu.europa.esig.dss.cades.signature.CAdESLevelBaselineT.extendCMSSignatures(CAdESLevelBaselineT.java:84)
    at eu.europa.esig.dss.cades.signature.CAdESSignatureExtension.extendCMSSignatures(CAdESSignatureExtension.java:170)
    at eu.europa.esig.dss.cades.signature.CAdESSignatureExtension.extendCMSSignatures(CAdESSignatureExtension.java:122)
    at eu.europa.esig.dss.cades.signature.CAdESLevelBaselineT.extendCMSSignatures(CAdESLevelBaselineT.java:52)
    at eu.europa.esig.dss.pades.signature.ExternalCMSService.buildCMSSignedData(ExternalCMSService.java:202)
    at eu.europa.esig.dss.pades.signature.PAdESService.generateCMSSignedData(PAdESService.java:246)
    at eu.europa.esig.dss.pades.signature.PAdESService.signDocument(PAdESService.java:209)

签名中似乎没有添加证书。以前有人遇到过同样的问题吗?我也希望有一个 LT 级别的工作示例。

java digital-signature pkcs#7 dss pades
1个回答
0
投票

我也有 DSS 集成问题,我们可以联系吗?

© www.soinside.com 2019 - 2024. All rights reserved.