[ https://issues.apache.org/jira/browse/PDFBOX-5568?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17691540#comment-17691540 ]
Piyush commented on PDFBOX-5568: -------------------------------- Hi Michael, I have updated the code, added message-digest attribute with the value of hashBytes and also made some changes while initialising contentSigner. But as told in description we fetch certificates and signedHash from some external provide (CSC). We don't have privateKey. So, after fetching signedHash from CSC, we are directly overriding the method getSignature of ContentSignature and returning that signedHash. ContentSigner cannot actually sign the bytes. Can you please provide way how I can resolve this? > Document getting corrupted on adding Signed Attributes > ------------------------------------------------------ > > Key: PDFBOX-5568 > URL: https://issues.apache.org/jira/browse/PDFBOX-5568 > Project: PDFBox > Issue Type: Bug > Components: Signing > Reporter: Piyush > Priority: Major > > While trying to digitally sign document using *filter* as > *_FILTER_ADOBE_PPKLITE_* and *subfilter* as > {*}_SUBFILTER_ETSI_CADES_DETACHED_{*}. For {*}ETSI_CADES_Detached{*}, a > signing attribute is needs to be added. I am fetching signed hash and > certificates from CSC. But after adding signing attribute, it is making the > document corrupt. Below is the screenshot for the reference . Seems like hash > is getting changed. > !https://i.stack.imgur.com/KKgRh.png! > > *Code snippet for reference:* > {code:java} > PDDocument document = PDDocument.load(inputStream); > outFile = File.createTempFile("signedFIle", ".pdf"); > Certificate[] certificateChain = //retrieve certificate chain from CSC > integration > setCertificateChain(certificateChain); > // sign > FileOutputStream output = new FileOutputStream(outFile); > IOUtils.copy(inputStream, output); > // create signature dictionary > PDSignature signature = new PDSignature(); > int accessPermissions = SigUtils.getMDPPermission(document); > if (accessPermissions == 1) > { > throw new IllegalStateException("No changes to the document are permitted due > to DocMDP transform parameters dictionary"); > } > signature.setFilter(PDSignature.FILTER_ADOBE_PPKLITE); > signature.setSubFilter(PDSignature.SUBFILTER_ETSI_CADES_DETACHED); > signature.setName("Test Name"); > signature.setLocation("Bucharest, RO"); > signature.setReason("PDFBox Signing"); > signature.setSignDate(Calendar.getInstance()); > Rectangle2D humanRect = new Rectangle2D.Float(location.getLeft(), > location.getBottom(), location.getRight(), location.getTop()); > PDRectangle rect = createSignatureRectangle(document, humanRect); > SignatureOptions signatureOptions = new SignatureOptions(); > signatureOptions.setVisualSignature(createVisualSignatureTemplate(document, > 0, rect, signature)); > signatureOptions.setPage(0); > document.addSignature(signature, signatureOptions); > ExternalSigningSupport externalSigning = > document.saveIncrementalForExternalSigning(output); > InputStream content = externalSigning.getContent(); > CMSSignedDataGenerator gen = new CMSSignedDataGenerator(); > X509Certificate cert = (X509Certificate) certificateChain[0]; > gen.addCertificates(new JcaCertStore(Arrays.asList(certificateChain))); > MessageDigest digest = MessageDigest.getInstance("SHA-256"); > // Use a buffer to read the input stream in chunks > byte[] buffer = new byte[4096]; > int bytesRead; > while ((bytesRead = content.read(buffer)) != -1) { > digest.update(buffer, 0, bytesRead); > } > byte[] hashBytes = digest.digest(); > ESSCertIDv2 certid = new ESSCertIDv2( > new AlgorithmIdentifier(new ASN1ObjectIdentifier("*****")), > MessageDigest.getInstance("SHA-256").digest(cert.getEncoded()) > ); > SigningCertificateV2 sigcert = new SigningCertificateV2(certid); > final DERSet attrValues = new DERSet(sigcert); > Attribute attr = new > Attribute(PKCSObjectIdentifiers.id_aa_signingCertificateV2, attrValues); > ASN1EncodableVector v = new ASN1EncodableVector(); > v.add(attr); > AttributeTable atttributeTable = new AttributeTable(v); > //Create a standard attribute table from the passed in parameters - certhash > CMSAttributeTableGenerator attrGen = new > DefaultSignedAttributeTableGenerator(atttributeTable); > final byte[] signedHash = // Retrieve signed hash from CSC. > ContentSigner nonSigner = new ContentSigner() { > @Override > public byte[] getSignature() > { return signedHash; } > @Override > public OutputStream getOutputStream() { > return new ByteArrayOutputStream(); > } > @Override > public AlgorithmIdentifier getAlgorithmIdentifier() { > return new DefaultSignatureAlgorithmIdentifierFinder().find( "SHA256WithRSA" > ); > } > }; > org.bouncycastle.asn1.x509.Certificate cert2 = > org.bouncycastle.asn1.x509.Certificate.getInstance(ASN1Primitive.fromByteArray(cert.getEncoded())); > JcaSignerInfoGeneratorBuilder sigb = new JcaSignerInfoGeneratorBuilder(new > JcaDigestCalculatorProviderBuilder().build()); > sigb.setSignedAttributeGenerator(attrGen); > gen.addSignerInfoGenerator(sigb.build(nonSigner, new > X509CertificateHolder(cert2))); > CMSTypedData msg = new CMSProcessableInputStream( inputStream); > CMSSignedData signedData = gen.generate((CMSTypedData)msg, false); > byte[] cmsSignature = signedData.getEncoded(); > inputStream.close(); > externalSigning.setSignature(cmsSignature); > IOUtils.closeQuietly(signatureOptions); > return new FileInputStream(outFile); > {code} > If I use subfilter as SUBFILTER_ADBE_PKCS7_DETACHED and don’t add > addtibutesTable, then it works fine. But for SUBFILTER_ETSI_CADES_DETACHED, > attributes needs to be added. -- This message was sent by Atlassian Jira (v8.20.10#820010) --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@pdfbox.apache.org For additional commands, e-mail: dev-h...@pdfbox.apache.org