Я пытаюсь подписать PDF-файл цифровой подписью с помощью аппаратного USB-токена (Hypersecure USB с eMudhra DSC) в Python. Цель состоит в том, чтобы создать видимую цифровую подпись в PDF-файле, которую можно будет проверить с помощью стандартных программ просмотра PDF-файлов, таких как Adobe Acrobat. Я использую следующие библиотеки:
PyKCS11 для взаимодействия с аппаратным токеном.
pikepdf для управления PDF-файлом и добавления данных подписи.
Результаты моего сценария показывают, что процесс подписания завершается успешно, и подписанный PDF-файл сохраняется. Однако:
Полученный PDF-файл не содержит видимой подписи.
Средства просмотра PDF-файлов не могут проверить цифровую подпись.
Словарные данные для подписи добавляются в аннотации PDF, но подпись не работает должным образом. Похоже, что данные цифровой подписи либо неполны, либо внедрены неправильно.
Ключевые моменты:
USB-токен успешно распознан, и я может получить закрытый ключ с помощью PyKCS11.
Данные хешируются и подписываются с помощью CKM_SHA256_RSA_PKCS.
Видимая аннотация добавляется в PDF-файл, но цифровая подпись не работает.
Среда:
Версия Python: (укажите версию, например, Python 3.8)
Библиотеки: PyKCS11, pikepdf, hashlib
Аппаратное обеспечение: Hypersecure USB-токен с eMudhra DSC.
Любая помощь, рекомендации или рабочие примеры будем очень признательны.
Я пытаюсь подписать PDF-файл цифровой подписью с помощью аппаратного USB-токена (Hypersecure USB с eMudhra DSC) в Python. Цель состоит в том, чтобы создать видимую цифровую подпись в PDF-файле, которую можно будет проверить с помощью стандартных программ просмотра PDF-файлов, таких как Adobe Acrobat. Я использую следующие библиотеки: PyKCS11 для взаимодействия с аппаратным токеном. pikepdf для управления PDF-файлом и добавления данных подписи. [code]from csv import reader, writer from pdfrw import PdfReader, PdfWriter from pdfrw.objects import PdfDict, PdfName, PdfString, PdfArray import hashlib import PyKCS11
self.session = None self.token_slot = None if self.pkcs11: self.login(pin)
def login(self, pin): try: slots = self.pkcs11.getSlotList(tokenPresent=True) if not slots: print("No tokens found.") return self.token_slot = slots[0] self.session = self.pkcs11.openSession(self.token_slot, PyKCS11.CKF_SERIAL_SESSION) self.session.login(pin) print("Logged in to token.") except Exception as e: print(f"Error during login: {e}")
def get_private_key(self): try: private_keys = self.session.findObjects([(PyKCS11.CKA_CLASS, PyKCS11.CKO_PRIVATE_KEY)]) if not private_keys: print("No private keys found.") return None for private_key in private_keys: key_type = self.session.getAttributeValue(private_key, [PyKCS11.CKA_KEY_TYPE])[0] if key_type == PyKCS11.CKK_RSA: print("Found valid RSA private key.") return private_key print("No valid RSA private key found.") except Exception as e: print(f"Error retrieving private key: {e}") return None
def sign(self, private_key, data): try: print(f"Signing data with private key: {private_key}") if private_key is None: print("Private key is None!") return None
def logout(self): try: if self.session: self.session.logout() self.session.closeSession() print("Logged out from token.") except Exception as e: print(f"Error logging out: {e}")
from pikepdf import Pdf, Name, Array, String, Dictionary
def sign_pdf(input_pdf_path, output_pdf_path, signature_text, signature_position, token_library_path, pin): try: # Initialize the signer signer = TokenSigner(token_library_path, pin) if signer is None: print("Signer initialization failed.") return
private_key = signer.get_private_key() if private_key is None: print("Private key not found. Exiting.") return
# Read the PDF and data for signing with open(input_pdf_path, "rb") as f: data_to_sign = f.read()
# Sign the data signed_data = signer.sign(private_key, data_to_sign) if signed_data is None: print("Error signing data.") return
# Open the input PDF with Pdf.open(input_pdf_path) as pdf: first_page = pdf.pages[0]
signature data = pikepdf.Dictionary(Type="/Annot")({ "/DA": "/Helv 0 Tf 0 g", "/FT": "/Sig", "/Rect": [ 100, 50, 300, 100 ], "/Subtype": "/Widget", "/T": "JAYESH MAHATO", "/Type": "/Annot", "/V": { "/Contents": "7d5653390f44bf06377b2ae5264538a3d0d4e9c524d33374ce8b6ad03033ea0354de6fde1d07fbded86679b4f2ebe29a0ffb139eb47ad5c7cd04b7486a671a783936c77fde54a871a00afb818e7acf7140c1570be07597c906d7d138645d3e011fcb9da1c788ba3cc79b31029fc7de1a53cadd50983ddcbb160c7fd78f5e968a53074217f56b85f2f23292f133a9086346c33fe68f13c8c41ab8c2fbbc45bb51648553ba68e9c76bd11e3e7616a67c5bde5f09f55639c8a5f38dcf3b96e5b02eb53c1af4bd3e4ff88db36d204e00cf78867967a7c577a910576e5bf68aec8966a1f18546016fc09c56c388a50ed9ad954608bf07c0c23ff549e10477138e413e" } }) PDF signed successfully and saved to: signed_sample_visible.pdf Logged out from token. [/code] Результаты моего сценария показывают, что процесс подписания завершается успешно, и подписанный PDF-файл сохраняется. Однако: Полученный PDF-файл не содержит видимой подписи. Средства просмотра PDF-файлов не могут проверить цифровую подпись. Словарные данные для подписи добавляются в аннотации PDF, но подпись не работает должным образом. Похоже, что данные цифровой подписи либо неполны, либо внедрены неправильно. Ключевые моменты: USB-токен успешно распознан, и я может получить закрытый ключ с помощью PyKCS11. Данные хешируются и подписываются с помощью CKM_SHA256_RSA_PKCS. Видимая аннотация добавляется в PDF-файл, но цифровая подпись не работает. Среда: Версия Python: (укажите версию, например, Python 3.8) Библиотеки: PyKCS11, pikepdf, hashlib Аппаратное обеспечение: Hypersecure USB-токен с eMudhra DSC. Любая помощь, рекомендации или рабочие примеры будем очень признательны.