[Please Help] problem in interrupted signing #281
-
I'm trying to implement interrupted signing because I want to use remote sign from Vault Transit. But Do you have any ideas on what could be causing this issue? Below is my full snippet code. from pyhanko.sign import signers, fields, timestamps
from pyhanko.sign.signers.pdf_signer import PdfTBSDocument
from pyhanko_certvalidator import ValidationContext
from pyhanko.pdf_utils.writer import BasePdfFileWriter
import asyncio
from pyhanko.keys import load_certs_from_pemder,load_cert_from_pemder
from pyhanko_certvalidator.registry import SimpleCertificateStore
from pyhanko.pdf_utils.incremental_writer import IncrementalPdfFileWriter
import hashlib
import base64
import requests
def instantiate_external_signer(sig_value: bytes):
cert_registry = SimpleCertificateStore()
return signers.ExternalSigner(
signing_cert = load_cert_from_pemder("self.crt"),
signature_value = sig_value,
cert_registry = cert_registry,
embed_roots = True,
)
async def preparePdf(fname):
with open(fname, 'rb') as doc:
ext_signer = instantiate_external_signer(sig_value = bytes(256))
pdf_signer = signers.PdfSigner(
signers.PdfSignatureMetadata(
field_name = 'sig',
subfilter = fields.SigSeedSubFilter.PADES,
md_algorithm = "sha256"
),
signer = ext_signer,
)
w = IncrementalPdfFileWriter(doc)
prep_digest, tbs_document, output = await pdf_signer.async_digest_doc_for_signing(w)
psi = tbs_document.post_sign_instructions
signed_attrs = await ext_signer.signed_attrs(
prep_digest.document_digest, 'sha256', use_pades = True
)
return prep_digest, signed_attrs, psi, output
async def getRemoteHash(base64_hash):
target_url = f"http://127.0.0.1:8200/v1/transit/sign/api-sign/sha2-256"
req_header = {"x-vault-token": "hvs.2NkhIwJSgZgkcZKTYyVi5pNS"}
req_body = {"input": base64_hash, "prehashed": "true"}
response = requests.post(target_url, data=req_body, headers=req_header)
output = response.json()
only_signature = output['data']['signature'].split(":")[2]
return base64.b64decode(only_signature)
async def signPdf(sig_value: bytes, prep_digest, signed_attrs, psi, output_handle):
ext_signer = instantiate_external_signer(sig_value)
sig_cms = await ext_signer.async_sign_prescribed_attributes(
'sha256',
signed_attrs=signed_attrs,
)
prep_digest.fill_with_cms(output_handle, sig_cms)
return output_handle
## prepare pdf for sign
prep_digest, \
signed_attrs, \
psi, \
output = asyncio.run(preparePdf('files\sample.pdf'))
## get the hash of the signed attributes and encode to base64 prepare to send to vault transit
send_hash = base64.b64encode(hashlib.sha256(signed_attrs.dump()).digest()).decode('utf-8')
## send the hash of the signed attributes to vault transit (remote service for sign)
hash = asyncio.run(getRemoteHash(send_hash))
## use output that get from vault transit to make signed pdf
output = asyncio.run(signPdf(hash, prep_digest, signed_attrs, psi, output))
## make sign document
pdfFile = open("files\sample_signed.pdf", "wb")
pdfFile.write(output.read())
pdfFile.close() |
Beta Was this translation helpful? Give feedback.
Answered by
MatthiasValvekens
Jul 9, 2023
Replies: 1 comment 3 replies
-
Hi @deaw0003, Hmm, not sure where the issue is at first glance. Can you upload a sample document? |
Beta Was this translation helpful? Give feedback.
3 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I had a quick look; your signed output indeed looks off... The signature data looks like an ECDSA signature (it's way too short to be RSA), but your signer's certificate (according to the ASN.1) is a self-signed cert with an RSA key?
Unless my assessment is wrong, this isn't a bug in pyHanko. Rather, it's a simple consequence of the fact that (for obvious reasons) the signature embedded in the file (in this case by the remote service you're using) needs to be produced using the same key pair as the one to which the certificate was issued ;).
Please contact your service provider's support for information on how to get your hands on the appropriate certificate. I can't really help you with …