Code: Select all
import pickle
import base64
def serialize_object_to_b64(obj):
"""Pickle-Objekt in Bytes serialisieren und Base64-codieren."""
pickled_bytes = pickle.dumps(obj)
b64_string = base64.b64encode(pickled_bytes).decode('utf-8')
return b64_string
def deserialize_object_from_b64(b64_string):
"""Base64-String zurück in Bytes und ent-picklen."""
pickled_bytes = base64.b64decode(b64_string.encode('utf-8'))
obj = pickle.loads(pickled_bytes)
return obj
< /code>
from pyhanko.sign import signers
from pyhanko.pdf_utils.incremental_writer import IncrementalPdfFileWriter
import asyncio #explained below
import nest_asyncio #explained below
nest_asyncio.apply() #explained below
cert_obj_before_save = signers.SimpleSigner.load_pkcs12(
pfx_file='test.pfx',
passphrase=b'#####',
)
serial_cert = serialize_object_to_b64(c1ert)
with open('testfile.txt', 'w') as file:
file.write(serial_cert)
[...] here I can stop and close jupyter lab then start it again (load the libraries again)
with open('testfile.txt', 'r') as file:
serial_cert_from_file = file.read()
cert_obj_AFTER_save = deserialize_object_from_b64(serial_cert_from_file)
with open('test.pdf', 'rb') as inf:
w = IncrementalPdfFileWriter(inf)
meta = signers.PdfSignatureMetadata(field_name='Signature3')
pdf_signer = signers.PdfSigner(meta, signer=cert_obj_AFTER_save)
with open('document-signed.pdf', 'wb') as outf:
pdf_signer.sign_pdf(w, output=outf)
< /code>
python script with tkinter started from console
I want a GUI. So during testing I have small python script with tkinter. If I load the pfx file and unlock it (signers.SimpleSigner.load_pkcs12()
# how I pickle the signer object
scert = serialize_object_to_b64(my_object)
with open("my_object_b64.txt", "w") as txt_file:
txt_file.write(scert)
# how it is unpickled
if os.path.exists("my_object_b64.txt"):
with open("my_object_b64.txt", "r") as txt_file:
scert = txt_file.read()
self.my_object = deserialize_object_from_b64(scert)
# how the pdf is signed
def sign_pdf(cert_object, file_path, new_path):
with open(file_path, 'rb') as infile:
writer = IncrementalPdfFileWriter(infile)
meta = signers.PdfSignatureMetadata(field_name='Signature3')
pdf_signer = signers.PdfSigner(meta, signer=cert_object)
with open(new_path, 'wb') as outfile:
pdf_signer.sign_pdf(writer, output=outfile)
< /code>
In jupyter lab I also have to import asyncio and nest_asyncio to get pyhanko to work. But this is not needed in the python script, I can sign pdfs with a pfx file. When I use a stored and unpickled object I noticed that the error changes if I import asyncio or not.
Error message with ´import asyncio´
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Users\x\AppData\Local\Programs\Python\Python311\Lib\tkinter\__init__.py", line 1967, in __call__
return self.func(*args)
^^^^^^^^^^^^^^^^
File "C:\Users\x\Documents\sign-venv\gui.py", line 329, in handle_drop
sign_pdf( dropped_file,
File "C:\Users\x\Documents\sign-venv\gui.py", line 48, in sign_pdf
pdf_signer = signers.PdfSigner(
^^^^^^^^^^^^^^^^^^
File "C:\Users\x\Documents\sign-venv\Lib\site-packages\pyhanko\sign\signers\pdf_signer.py", line 1082, in __init__
mech = self.signer.get_signature_mechanism_for_digest(None)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\x\Documents\sign-venv\Lib\site-packages\pyhanko\sign\signers\pdf_cms.py", line 407, in get_signature_mechanism_for_digest
algo = self.signing_cert.public_key.algorithm
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\x\Documents\sign-venv\Lib\site-packages\asn1crypto\x509.py", line 2538, in public_key
return self['tbs_certificate']['subject_public_key_info']
~~~~^^^^^^^^^^^^^^^^^^^
File "C:\Users\x\Documents\sign-venv\Lib\site-packages\asn1crypto\core.py", line 3508, in __getitem__
self._parse_children()
File "C:\Users\x\Documents\sign-venv\Lib\site-packages\asn1crypto\core.py", line 3988, in _parse_children
raise e
File "C:\Users\x\Documents\sign-venv\Lib\site-packages\asn1crypto\core.py", line 3895, in _parse_children
cls._precomputed_specs[field] or self._determine_spec(field))
~~~~~~~~~~~~~~~~~~~~~~^^^^^^^
TypeError: 'NoneType' object is not subscriptable
while parsing asn1crypto.x509.Certificate
< /code>
Error message without ´import asyncio´
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Users\x\AppData\Local\Programs\Python\Python311\Lib\tkinter\__init__.py", line 1967, in __call__
return self.func(*args)
^^^^^^^^^^^^^^^^
File "C:\Users\x\Documents\sign-venv\gui.py", line 325, in handle_drop
sign_pdf( dropped_file,
File "C:\Users\x\Documents\sign-venv\gui.py", line 44, in sign_pdf
pdf_signer = signers.PdfSigner(
^^^^^^^^^^^^^^^^^^
File "C:\Users\x\Documents\sign-venv\Lib\site-packages\pyhanko\sign\signers\pdf_signer.py", line 1082, in __init__
mech = self.signer.get_signature_mechanism_for_digest(None)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\x\Documents\sign-venv\Lib\site-packages\pyhanko\sign\signers\pdf_cms.py", line 407, in get_signature_mechanism_for_digest
algo = self.signing_cert.public_key.algorithm
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\x\Documents\sign-venv\Lib\site-packages\asn1crypto\x509.py", line 2538, in public_key
return self['tbs_certificate']['subject_public_key_info']
~~~~^^^^^^^^^^^^^^^^^^^
File "C:\Users\x\Documents\sign-venv\Lib\site-packages\asn1crypto\core.py", line 3511, in __getitem__
if key not in self._field_map:
^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: argument of type 'NoneType' is not iterable
< /code>
I do not understand the difference between jupyter lab and the script.