我试图在Office2016中对XLSX文件进行签名并添加时间戳服务器,我使用了apache的代码,但它似乎不起作用,每个签名结果都返回XAdES。我期望的结果是XAdES。下面是带有时间戳服务器签名的apache poi的源代码:
void testSignEnvelopingDocument() throws Exception {
String testFile = "hello-world-unsigned.xlsx";
File sigCopy = testdata.getFile(testFile);
UnsynchronizedByteArrayOutputStream bos = new UnsynchronizedByteArrayOutputStream(50000);
final String execTimestr;
try (OPCPackage pkg = OPCPackage.open(copy(sigCopy), PackageAccess.READ_WRITE)) {
initKeyPair();
final X509CRL crl = generateCrl(x509, keyPair.getPrivate());
// setup
SignatureConfig signatureConfig = new SignatureConfig();
signatureConfig.setKey(keyPair.getPrivate());
/*
* We need at least 2 certificates for the XAdES-C complete certificate
* refs construction.
*/
List<X509Certificate> certificateChain = new ArrayList<>();
certificateChain.add(x509);
certificateChain.add(x509);
signatureConfig.setSigningCertificateChain(certificateChain);
signatureConfig.addSignatureFacet(new OOXMLSignatureFacet());
signatureConfig.addSignatureFacet(new EnvelopedSignatureFacet());
signatureConfig.addSignatureFacet(new KeyInfoSignatureFacet());
signatureConfig.addSignatureFacet(new XAdESSignatureFacet());
signatureConfig.addSignatureFacet(new XAdESXLSignatureFacet());
// check for internet, no error means it works
boolean mockTsp = (getAccessError("http://timestamp.comodoca.com/rfc3161", true, 10000) != null);
// http://timestamping.edelweb.fr/service/tsp
// http://tsa.belgium.be/connect
// http://timestamp.comodoca.com/authenticode
// http://timestamp.comodoca.com/rfc3161
// http://services.globaltrustfinder.com/adss/tsa
signatureConfig.setTspUrl("http://timestamp.comodoca.com/rfc3161");
signatureConfig.setTspRequestPolicy(null); // comodoca request fails, if default policy is set ...
signatureConfig.setTspOldProtocol(false);
signatureConfig.setXadesDigestAlgo(HashAlgorithm.sha512);
signatureConfig.setXadesRole("Xades Reviewer");
signatureConfig.setSignatureDescription("test xades signature");
execTimestr = signatureConfig.formatExecutionTime();
//set proxy info if any
String proxy = System.getProperty("http_proxy");
if (proxy != null && proxy.trim().length() > 0) {
signatureConfig.setProxyUrl(proxy);
}
if (mockTsp) {
TimeStampService tspService = (signatureInfo, data, revocationData) -> {
revocationData.addCRL(crl);
return "time-stamp-token".getBytes(LocaleUtil.CHARSET_1252);
};
signatureConfig.setTspService(tspService);
} else {
TimeStampServiceValidator tspValidator = (validateChain, revocationData) -> {
for (X509Certificate certificate : validateChain) {
LOG.atDebug().log("certificate: {}", certificate.getSubjectX500Principal());
LOG.atDebug().log("validity: {} - {}", certificate.getNotBefore(), certificate.getNotAfter());
}
};
signatureConfig.setTspValidator(tspValidator);
signatureConfig.setTspOldProtocol(signatureConfig.getTspUrl().contains("edelweb"));
}
final RevocationData revocationData = new RevocationData();
revocationData.addCRL(crl);
OCSPResp ocspResp = createOcspResp(x509, x509, x509, keyPair.getPrivate(), cal.getTimeInMillis());
revocationData.addOCSP(ocspResp.getEncoded());
RevocationDataService revocationDataService = revocationChain -> revocationData;
signatureConfig.setRevocationDataService(revocationDataService);
// operate
SignatureInfo si = new SignatureInfo();
si.setOpcPackage(pkg);
si.setSignatureConfig(signatureConfig);
try {
si.confirmSignature();
} catch (RuntimeException e) {
// only allow a ConnectException because of timeout, we see this in Jenkins from time to time...
if (e.getCause() == null) {
throw e;
}
if ((e.getCause() instanceof ConnectException) || (e.getCause() instanceof SocketTimeoutException)) {
assumeFalse(e.getCause().getMessage().contains("timed out"),
"Only allowing ConnectException with 'timed out' as message here, but had: " + e);
} else if (e.getCause() instanceof IOException) {
assumeFalse(e.getCause().getMessage().contains("Error contacting TSP server"),
"Only allowing IOException with 'Error contacting TSP server' as message here, but had: " + e);
} else if (e.getCause() instanceof RuntimeException) {
assumeFalse(e.getCause().getMessage().contains("This site is cur"),
"Only allowing RuntimeException with 'This site is cur' as message here, but had: " + e);
}
throw e;
}
}发布于 2021-10-14 09:05:28
作为参考,我添加了bugzilla条目,它将很快包含修复。对于POI5.0.0的用户,您可以复制XAdESXLSignatureFacet源代码并在用户包中提供它。相应的测试用例是TestSignatureInfo中的“TestSignatureInfo”
https://stackoverflow.com/questions/69355533
复制相似问题