Проверить цифровую подпись с помощью цепочки сертификатов в java - PullRequest
0 голосов
/ 20 февраля 2020

я пытаюсь подписать pdf с помощью цифровой подписи, я отправляю га sh значение pdf в REST API, он подписывает pdf с помощью личного ключа пользователя и возвращает данные в формате CMS. Я получил цепочку сертификатов от CMS. Теперь мне нужно проверить оригинальный PDF с помощью цепочки сертификатов и добавить подпись в PDF. Я использую B C и Itextpdf

public static String verifyPdf(byte[] toVerify, byte[] signedByte, String origFile, String signedFile) throws Exception {

//        CMSSignedData cms = new CMSSignedData(signedByte);
//        Store store = cms.getCertificates();
//        System.out.println("Store:" + store);

        String result = "";
        X509Certificate certificate = null;
        SignedData signedData = bytesToPkcs7SignedData(signedByte);
        Certificate[] certs = new Certificate[1];

        X509CertificateChain chain = new X509CertificateChain();
        chain.addAll(readCerts(signedData));
        certificate = chain.get(0);
//        System.out.println("Certificate: " + certificate);
        certs[0] = chain.get(0);
        System.out.println("Signature:" + certificate);
//        for (X509Certificate x5 : chain) {
//            System.out.println(x5);
//        }


        if(certificate != null){
            PublicKey pk = certificate.getPublicKey();
            OcspClient ocspClient = new OcspClientBouncyCastle();
            TSAClient tsaClient = null;
            for (X509Certificate x5 : chain) {
                String tsaUrl = CertificateUtil.getTSAURL(x5);
                if (tsaUrl != null) {
                    tsaClient = new TSAClientBouncyCastle(tsaUrl);
                    break;
                }
            }
            List<CrlClient> crlList = new ArrayList<CrlClient>();
            crlList.add(new CrlClientOnline(certs));
            sign(origFile,signedFile, certs, pk, DigestAlgorithms.SHA256, null,
                    MakeSignature.CryptoStandard.CMS, "User Signature", "", crlList, ocspClient, tsaClient, 0);
        }
        return result;
    }

Я думаю, что это поле подписи является подписью пользователя с темой с именем пользователя et c, что внутри цепочки сертификатов enter image description here

Это функция подписи (я проверил ее, используя Keypairs, подписал pdf и добавил в pdf, она работает. Но в этом случае у меня нет личного ключа, поэтому я не знаю, как добавить подпись в pdf):

 public static void sign(String src,
                            String dest,
                            Certificate[] chain,
                            PublicKey pk,
                            String digestAlgorithm,
                            String provider,
                            MakeSignature.CryptoStandard subfilter,
                            String reason,
                            String location,
                            Collection<CrlClient> crlList,
                            OcspClient ocspClient,
                            TSAClient tsaClient,
                            int estimatedSize)
            throws GeneralSecurityException, IOException, DocumentException {
        PdfReader reader = new PdfReader(src);
        com.itextpdf.kernel.pdf.PdfReader pdfReader = new com.itextpdf.kernel.pdf.PdfReader(src);

        FileOutputStream os = new FileOutputStream(dest);
        OutputStream out = new FileOutputStream(dest);

        AcroFields acroFields = reader.getAcroFields();
        PdfSigner signer = new PdfSigner(pdfReader, out, new StampingProperties().useAppendMode());

        List<String> names = acroFields.getSignatureNames();
        for (String name : names) {
            System.out.println("Signature name: " + name);
            System.out.println("Signature covers whole document: " + acroFields.signatureCoversWholeDocument(name));
            System.out.println("Document revision: " + acroFields.getRevision(name) + " of " + acroFields.getTotalRevisions());
            PdfPKCS7 pkcs = acroFields.verifySignature(name);
            System.out.println("Subject: " + CertificateInfo.getSubjectFields(pkcs.getSigningCertificate()));
            System.out.println("Document verifies: " + pkcs.verify());
        }

        PdfStamper stamper = PdfStamper.createSignature(reader, os, '\0');
        PdfSignatureAppearance appearance = stamper.getSignatureAppearance();
        appearance.setReason(reason);
        appearance.setLocation(location);
        appearance.setVisibleSignature(new Rectangle(100, 100, 200, 200), 1, "sig");
        appearance.setCertificate(chain[0]);

//        ExternalSignature pks = new PrivateKeySignature(pk, digestAlgorithm, provider);
        ExternalDigest digest = new BouncyCastleDigest();
//        MakeSignature.signDetached(appearance, digest, pks, chain, crlList, ocspClient, tsaClient, estimatedSize, subfilter);

        ExternalSignatureContainer external = new ExternalBlankSignatureContainer(PdfName.ADOBE_PPKLITE, PdfName.ADBE_PKCS7_DETACHED);
        MakeSignature.signExternalContainer(appearance, external, 8192);

    }

Я протестировал функцию знака с помощью пар ключей и мог добавить подпись. PDF выглядит следующим образом: enter image description here

В моем неудачном случае я получил это:

...