我正在尝试使用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()
实现没有被执行?