Use CAdES with Signer.async_sign_raw #339
-
The esign service I use to sign my PDF documents recently did some changes to be compliant with the EU commission regarding electronic signatures. PdfSigner pdfSigner = new PdfSigner(pdfReader,
new FileStream(DestinationSignedPdf, FileMode.OpenOrCreate), stampingProperties);
pdfSigner.GetSignatureAppearance().SetPageNumber(1).SetReason(Reason).SetLocation(Location);
pdfSigner.SetFieldName(SignatureFieldName);
IExternalSignature pks = new ServerSignature(Iteration, SourcePlainPdf, AuthenticationToken, QscdServerBaseAddress, CertificateAlias, Seed, Secret, HashAlgorithmOID);
// Change from this:
// pdfSigner.SignDetached(pks, certificates.ToArray(), null, null, null, 0, PdfSigner.CryptoStandard.CMS); // PKCS7-B
// To this:
pdfSigner.SignDetached(pks, certificates.ToArray(), null, null, null, 0, PdfSigner.CryptoStandard.CADES); // PAdES-BASELINE-B I noticed the Signer class has some signing methods where I can just pass I suppose I need to set a This is my code so far: class ExternalServiceSigner(Signer):
prefer_pss = False
embed_roots = True
async def async_sign_raw(self, data: bytes, digest_algorithm: str, dry_run=False) -> bytes:
if dry_run:
return bytes(256)
hash_spec = get_pyca_cryptography_hash(self.signature_mechanism.hash_algo)
md = hashes.Hash(hash_spec)
md.update(data)
# External service request
response = request_external_service_to_sign_hash(
b64encode(md.finalize()).decode("utf-8"))
return b64decode(response.json()[0]["hashSig"])
my_signer = ExternalServiceSigner(
signing_cert=cert,
signature_mechanism=algos.SignedDigestAlgorithm(
{'algorithm': 'sha256_rsa'}
))
meta = signers.PdfSignatureMetadata(field_name='sig')
output = signers.sign_pdf(w, meta, signer=my_signer, output=None)
with open(f'signed-file-{time.time()}.pdf', 'wb') as outf:
outf.write(output.getvalue()) Thank you for your help. |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 4 replies
-
Hi @ruimelodev, You're in luck: with that calling convention you can just pass The CAdES signed attributes thing is for adding optional attributes that are defined in CAdES but not in "core" CMS. They're not needed for baseline compliance, regardless of the level. |
Beta Was this translation helpful? Give feedback.
Hi @ruimelodev,
You're in luck: with that calling convention you can just pass
use_pades=True
(EDIT: sorry,subfilter=PADES
is the current syntax) inPdfSignatureMetadata
and pyHanko will do the rest. No need to change your custom signer, but you might need some more config if you also want timestamps to be included (depends on the specific PAdES level you need).The CAdES signed attributes thing is for adding optional attributes that are defined in CAdES but not in "core" CMS. They're not needed for baseline compliance, regardless of the level.