כיצד לאבטח ולחתום על מסמכי 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()של recipients רשימה — תעודה שהונפקה מחדש עם זוג מפתחות חדש לא תפענח נתונים שהוצפנו תחת הישנה.

שאלות נפוצות

האם ניתן להצפין מסמך ליותר מנמען אחד?

כן — recipients ב-Document.Save() של אפשרות encrypt מקבלת מערך; כל מפתח פרטי תואם של נמען יכול לפתוח את הקובץ שנוצר.

איזה פורמט חתימה מייצר Document.Sign()?

העברת subFilter: 'PAdES' באפשרויות החתימה מייצרת חתימה תואמת PAdES; השמטת אותו משתמשת בתת-מסנן החתימה ברירת המחדל של הספרייה.

איך אני בודק האם מסמך מוסמך או רק חתום?

בדוק את השדה docMDP ב-SignatureReport שמוחזר על ידי Document.VerifySignatures() — חתימת הסמכה מדווחת על החלטת הרשאה DocMDP; חתימה של רק אישור אינה מדווחת זאת.

האם Permissions משוחזרים לאחר Document.Open() נאכפים על-ידי הספרייה?

לא — opened.Permissions מדווחת על דגלי ההרשאות שנרשמו בקובץ המוצפן לצורך בדיקה; אכיפתם ביישום היא אחריות הקורא.

ראה גם

 עברית