Як захистити та підписати PDF-документи в TypeScript

Як захистити та підписати PDF-документи в TypeScript

У цьому посібнику показано, як шифрувати, сертифікувати, підписувати та перевіряти PDF-документи за допомогою Aspose.PDF FOSS для TypeScript. Document.Save() і Document.Open() здійснюють шифрування відкритим ключем до сертифікатів отримувачів, тоді як Document.Certify(), Document.Sign() і Document.VerifySignatures() працюють з цифровими підписами у стилі PAdES. Потрібен Node.js 22 або новіший.

Покроковий посібник

Крок 1: Встановити пакет

git clone https://github.com/aspose-pdf-foss/Aspose.PDF-FOSS-for-TypeScript.git
cd Aspose.PDF-FOSS-for-TypeScript
npm install
npm run build

Перевірте встановлення, імпортуючи клас Document у новий файл TypeScript — цей рядок має успішно виконатися без помилок після встановлення пакету:

import { Document } from '@asposefoss/pdf';

Крок 2: Імпортувати необхідні класи

Імпортуйте Document, щоб відкривати, зберігати, підписувати та перевіряти файл; кроки підпису та шифрування нижче передають прості об’єкти параметрів, тому додаткові імпорти не потрібні:

import { Document } from '@asposefoss/pdf';

Крок 3: Шифрування документа для сертифікатів одержувачів

Document.Save() приймає параметр encrypt, що містить один або кілька recipients, кожен ідентифікований сертифікатом (рядок PEM або байти DER), algorithm та спільними permissions:

const doc = Document.OpenFile('report.pdf');

const bytes = doc.Save({
  encrypt: {
    recipients: [{ certificate: recipientCertPem }],
    algorithm: 'aes256', // 'aes256' (default) | 'aes128' | 'rc4'
    permissions: { copying: false }, // shared across all recipients
  },
});

Крок 4: Відкрити зашифрований документ

Передайте параметр recipient до Document.Open() з відповідним приватним ключем і сертифікатом або з пакетом PKCS#12:

const opened = Document.Open(bytes, {
  recipient: { privateKey, certificate: recipientCertPem },
  // or: recipient: { pkcs12: p12Bytes, passphrase: '…' },
});

console.log(opened.Permissions); // recovered permission flags (not enforced)

Крок 5: Сертифікувати та підписати документ

Document.Certify() та Document.Sign() обидва є асинхронними і приймають ідентичність (certificate + privateKey) плюс параметри, що описують поле підпису, його вигляд і причину. Сертифікація повинна відбуватись першою, для усього файлу; подальші підписи схвалення додаються поступово після цього:

async function certifyAndSign(sourcePath: string, signaturePageIndex: number): Promise<void> {
  const certifying = Document.OpenFile(sourcePath);
  await certifying.Certify(
    { certificate: authorCert, privateKey: authorKey },
    {
      permissions: 'form-fill',
      reason: 'Certifying the document',
      fieldName: 'Certification',
      appearance: { page: signaturePageIndex, rect: [400, 100, 550, 140] },
    },
  );
  const certifiedBytes = certifying.Save();

  const approving = Document.Open(certifiedBytes);
  await approving.Sign(
    { certificate: approverCert, privateKey: approverKey },
    { reason: 'Approved for publication', fieldName: 'Approval', subFilter: 'PAdES' },
  );
  approving.WriteTo('signed.pdf');
}

Крок 6: Перевірка підписів

Document.VerifySignatures() є асинхронним і повертає один SignatureReport на поле підпису, кожен з яких повідомляє про криптографічний integrity, дійсність signature та чи coversWholeFile:

async function verify(path: string): Promise<void> {
  const doc = Document.OpenFile(path);
  const reports = await doc.VerifySignatures();
  for (const r of reports) {
    console.log(`${r.name}: integrity=${r.integrity} signature=${r.signature} `
      + `coversWholeFile=${r.coversWholeFile} docMDP=${r.docMDP}`);
  }
}

Типові проблеми та рішення

Document.Sign() / Document.Certify() викинути або зависнути. Обидва асинхронні — await виклик. Забування await залишає повернену обіцянку невирішеною, а запис відбувається до завершення підпису.

Пізніший підпис схвалення анулює сертифікацію. Підписуйте інкрементно: спочатку збережіть сертифіковані байти (certifying.Save()), відкрийте їх за допомогою Document.Open(), потім викличте Sign() на тому повторно відкритому документі — запис повного перезапису замість інкрементного додавання порушує сертифікації /ByteRange контрольна сума.

VerifySignatures() reports coversWholeFile: false для першого підпису, але true для останнього. Це очікується для ланцюжка certify-then- sign: сертифікація була підписана до того, як схвалення було додано, тому лише найновішого підпису /ByteRange поширюється до кінця файлу.

Розшифрування не вдається з правильним приватним ключем. Підтвердіть certificate передано до recipient відповідає точному сертифікату, яким документ був зашифрований у Document.Save()’s recipients список — сертифікат, переоформлений з новою парою ключів, не зможе розшифрувати дані, зашифровані старим.

Поширені запитання

Чи можна зашифрувати документ для більш ніж одного отримувача?

Так — recipients у параметрі encrypt Document.Save() приймає масив; будь-який відповідний приватний ключ отримувача може відкрити отриманий файл.

Який формат підпису створює Document.Sign()?

Передача subFilter: 'PAdES' у параметрах підпису створює підпис, сумісний з PAdES; якщо його опустити, використовується типовий субфільтр підпису бібліотеки.

Як перевірити, чи документ сертифікований, а не лише підписаний?

Перевірте поле docMDP у SignatureReport, який повертає Document.VerifySignatures() — підпис сертифікації містить рішення про дозволи DocMDP; підпис лише затвердження цього не містить.

Чи застосовує бібліотека відновлені Permissions після Document.Open()?

Ні — opened.Permissions повідомляє про прапорці дозволів, записані у зашифрованому файлі, для перегляду; застосування їх у застосунку є відповідальністю викликаючого.

Дивіться також

 Українська