Reputation: 23
I am trying to attach the certificate in the digitally signed pdf document with PDFBOX in JAVA.
I didn't get any error during the whole process of attaching the certificate and signature. I am using a certificate and signature the Certificate Authority (CA) provided.
Then, when I try to open that PDF in Acrobat Adobe, it gives an error that says the certificate is invalid and the certificate details are not present in the signature panel.
I tried to check if the signature field is present or not with this line of code and I can say the signature field is present in pdf file.
What could be the cause of the not showing the certificate details?
The signature details pop should be visible the certificate should be valid, and it should say that the file is certified by XXXX.
private void attachNotariusVerifiedCertificate(String signRequestId, FileOutputStream output, PDDocument unsignedDocument) throws Exception
{
loadExternalCert(eSignCertProvider.getCertificateChain());
ExternalSigningSupport externalSigningSupport = unsignedDocument.saveIncrementalForExternalSigning(output);
byte[] cmsSignature = signExternally(externalSigningSupport.getContent(), signRequestId);
externalSigningSupport.setSignature(cmsSignature);
}
private byte[] signExternally(InputStream content, String signRequestId) throws IOException
{
List<Certificate> externalCertificates;
JcaCertStore jcaCertStore;
CMSSignedDataGenerator generator;
MessageDigest messageDigest;
byte[] documentHash;
byte[] signedDocumentHash;
ContentSigner contentSigner;
JcaSignerInfoGeneratorBuilder jcaSignerInfoGeneratorBuilder;
try {
externalCertificates = new ArrayList<>(Arrays.asList(externalCertificateChain));
jcaCertStore = new JcaCertStore(externalCertificates);
generator = new CMSSignedDataGenerator();
generator.addCertificates(jcaCertStore);
messageDigest = MessageDigest.getInstance("SHA-256");
documentHash = messageDigest.digest(content.readAllBytes());
signedDocumentHash = eSignCertProvider.signDocumentHash(documentHash, signRequestId);
contentSigner = new ContentSigner()
{
@Override
public byte[] getSignature() {
return signedDocumentHash;
}
@Override
public OutputStream getOutputStream() {
return new ByteArrayOutputStream();
}
@Override
public AlgorithmIdentifier getAlgorithmIdentifier() {
return new DefaultSignatureAlgorithmIdentifierFinder().find("SHA256WithRSA");
}
};
jcaSignerInfoGeneratorBuilder = new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().build());
jcaSignerInfoGeneratorBuilder.setDirectSignature(true);
org.bouncycastle.asn1.x509.Certificate certificateX509 = org.bouncycastle.asn1.x509.Certificate.getInstance(ASN1Primitive.fromByteArray(externalCertificateChain[0].getEncoded()));
generator.addSignerInfoGenerator(jcaSignerInfoGeneratorBuilder.build(contentSigner, new X509CertificateHolder(org.bouncycastle.asn1.x509.Certificate.getInstance(X509CertificateStructure.getInstance(certificateX509)))));
CMSSignedData signedData = generator.generate(new CMSAbsentContent(), false);
return signedData.getEncoded();
} catch (Exception e) {
loggingService.error(LOGGER_NAME, "Exception in signExternally()", e);
throw new IOException(e);
}
}
public byte[] signDocumentHash(byte[] hash, String signRequestId) throws Exception
{
byte[] signedDocumentHash;
ASN1EncodableVector digestInfoVector;
DERSequence derSequence;
String base64DigestInfo;
String requestBodyJson;
String signedPayload;
String response;
String signatureBase64;
try {
digestInfoVector = new ASN1EncodableVector();
digestInfoVector.add(new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha256, DERNull.INSTANCE));
digestInfoVector.add(new DEROctetString(hash));
derSequence = new DERSequence(digestInfoVector);
base64DigestInfo = Base64.getEncoder().encodeToString(derSequence.getEncoded());
requestBodyJson = signRequestPayload(base64DigestInfo, signRequestId);
signedPayload = signedPayload(requestBodyJson, serverConfig.geteSignConfig().getSignatureKey());
response = sign(signedPayload).getBody();
ObjectMapper objectMapper = new ObjectMapper();
Map map = objectMapper.readValue(response, Map.class);
signatureBase64 = map.get("sig").toString();
signedDocumentHash = Base64.getDecoder().decode(String.valueOf(signatureBase64.toCharArray()));
return signedDocumentHash;
} catch (Exception ex) {
loggingService.error(LOGGER_NAME, "Exception in sign document hash reason:: " + ex.getMessage(), ex);
throw ex;
}
}
This is the whole code we use.
Upvotes: 0
Views: 118