使用PDFBox将时间戳添加到PDF文件

时间:2018-04-03 09:42:03

标签: java pdfbox trusted-timestamp

我正在尝试使用Apache PDFBox 2.0.8向pdf文档添加TSA时间戳。

这是设置和处理时间戳的方法:

@Override
    public void timestampPDFDocument() throws IOException, SignatureException, COSVisitorException {
        final PDSignature signature = new PDSignature();
        signature.setType(COSName.DOC_TIME_STAMP);
        signature.setFilter(PDSignature.FILTER_ADOBE_PPKLITE);
        signature.setSubFilter(COSName.getPDFName("ETSI.RFC3161"));
        signature.setSignDate(Calendar.getInstance());
        signature.setReason("test");

        final PDDocument pdf = PDDocument.load(dataSrv.currentCtxFile());

        final TimestampPDFImplementation sig = new TimestampPDFImplementation(cHTTPProxyPassword, cHTTPProxyUsername, ctstHttpUrl, signingCrt);

        SignatureOptions options = new SignatureOptions();
        pdf.addSignature(signature, sig, options);

        pdf.save(dataSrv.createNewAndHandBufferedOutputStream());
        pdf.close();
    }

我将每个请求的文件存储在内存中,以便更轻松地操作“共享资源”,这就是pdf来自加载的地方:

PDDocument.load(dataSrv.currentCtxFile());

我对SignatureInterface的实施:

public class TimestampPDFImplementation implements SignatureInterface {

    String cHTTPProxyPassword;
    String cHTTPProxyUsername;
    String ctstHttpUrl;
    String signingCrt;

    public TimestampPDFImplementation(String cHTTPProxyPassword, String cHTTPProxyUsername, String ctstHttpUrl, String signingCrt) {
        this.cHTTPProxyPassword = cHTTPProxyPassword;
        this.cHTTPProxyUsername = cHTTPProxyUsername;
        this.ctstHttpUrl = ctstHttpUrl;
        this.signingCrt = signingCrt;
    }

    @Override
    public byte[] sign(InputStream inputStream) throws SignatureException, IOException {
        TElHTTPTSPClient tspClient = new TElHTTPTSPClient();
        TElHTTPSClient httpClient = new TElHTTPSClient();
        TElMemoryCertStorage certStorage = new TElMemoryCertStorage();

        if (!Strings.isNullOrEmpty(cHTTPProxyPassword) &&
                !Strings.isNullOrEmpty(cHTTPProxyUsername)) {
            // set the http client

            TElHTTPRequestParams requestParams = new TElHTTPRequestParams();
            requestParams.setUsername(cHTTPProxyUsername);
            requestParams.setPassword(cHTTPProxyPassword);

            httpClient.setRequestParameters(requestParams);
        }

        tspClient.setHTTPClient(httpClient);

        tspClient.setHashAlgorithm(SBConstants.SB_ALGORITHM_DGST_SHA512);
        tspClient.setURL(ctstHttpUrl);

        certStorage.add(loadCrt(signingCrt, ""), false);
        httpClient.setCertStorage(certStorage);

        tspClient.setIncludeCertificates(true);
        tspClient.setOnHTTPError(setErrEvntHandler());
        httpClient.setOnCertificateValidate(crtValidateEvent());

        TElTSPReply tspReply = new TElTSPReply();
        tspClient.timestamp(ByteStreams.toByteArray(inputStream), tspReply);

        tspClient.Destroy();

        if (tspReply.FailureInfo != 0 || tspReply.ServerResult != 0)
            throw new SignatureException(
                    String.format("timestamping service error; FailureInfo:  %s, ServerResult: %s", tspReply.FailureInfo, tspReply.ServerResult)
            );

        return tspReply.ReplyCMS;
    }


    private TSBHTTPTSPErrorEvent setErrEvntHandler() {
        TSBHTTPTSPErrorEvent.Callback callback = (tObject, i) -> {
            System.out.println();
        };

        return new TSBHTTPTSPErrorEvent(callback);
    }

    private TSBCertificateValidateEvent crtValidateEvent() {
        TSBCertificateValidateEvent.Callback callback = (tObject, tElX509Certificate, tElX509CertificateValidateResult) -> {

//            tElX509Certificate.loadFromFileAuto(signingCrt, "");
            tElX509CertificateValidateResult.Validity = TSBCertificateValidity.cvOk;
            tElX509CertificateValidateResult.Reason = 0;
        };

        return new TSBCertificateValidateEvent(callback);
    }

    private TElX509Certificate loadCrt(String filename, String crtPass) {
        TElX509Certificate certificate = new TElX509CachedCertificate();
        certificate.loadFromFileAuto(filename, crtPass);
        return certificate;
    }
}

签名逻辑应该没问题,我之前已经验证过。

我的所有问题是byte[] sign(InputStream inputStream)方法永远不会被执行。没有例外。 保存的PDF的大小增加,但是当绕过时间戳逻辑时,没有任何效果。

从注入timestampPDFDocument()调用

@Service到应用程序事件侦听器并从那里调用。

那么,我在这里正确执行TSA时间戳的原因是什么?为什么sign()实现没有被执行?

0 个答案:

没有答案