דגל הרשאה ב-PDF אינו מנעול. הוא בקשה שהקובץ מגיש לכל תוכנה שפותחת אותו, וצופן חופשי להתעלם ממנה. עובדה יחידה זו קובעת כיצד עליך להמשיג כל בחירה אחרת בדף זה. סודיות אמיתית מגיעה ממקום אחד בלבד: הצפנת AES-256 המאובטחת בסיסמה שלקורא אין. כל השאר — תיבות הסימון "ללא הדפסה" ו"ללא העתקה" — היא מדיניות שתוכנות תואמות מסכימות לכבד ותוכנות עוינות לא. ערבב את שתי השכבות הללו ותשלח משהו שנראה מאובטח בהדגמה אך מדליף בשטח
HotPDF הוא רכיב PDF מקורי מסוג VCL עבור Delphi ו-C++Builder, והוא חושף את מודל ההגנה של ISO 32000 דרך קבוצה קטנה של מאפיינים. המאפיינים קלים להגדרה. הדבר הקשה הוא לדעת איזה מהם מספק הגנה קריפטוגרפית ואיזה מספק הצעה מנומסת, ולהקצות אותם בסדר הנכון כדי שההצפנה שביקשת היא אכן ההצפנה שתקבל
מה שתי הסיסמאות מבטיחות למעשה
הצפנת PDF מגדירה שתי אישורים בעלי תפקידים שונים, וערבוב ביניהם היא שגיאת העיצוב הנפוצה ביותר בקוד פלט מוגן. סיסמת המשתמש שומרת על פענוח ההצפנה. ללא סיסמת המשתמש, או ללא סיסמת הבעלים, קורא תואם אינו יכול לשחזר את מפתח הקובץ והתוכן נשאר בלתי קריא קריפטוגרפית. סיסמת הבעלים שומרת על הגדרות ההרשאות: קורא שמקבל את סיסמת הבעלים מקבל גישה מלאה ללא קשר לדגלי ההגבלה
ביטי ההרשאות עומדים על בסיס חלש יותר. הדפסה, חילוץ תוכן, מילוי טפסים — כל אחד הוא דגל שצופן קורא ובוחר לכבד (ISO 32000-2 §7.6.4). הצפנה מגינה על הבייטים. דגלי ההרשאות רק מורים לתוכנות תואמות, ועושות זאת בדיעבד. כל מי שפותח את המסמך עם סיסמת המשתמש כבר מחזיק את התוכן המפוענח בזיכרון, כך ש"ללא העתקה" ו"ללא הדפסה" משמעותיים לצופן מתנהג היטב וחסרי משמעות לצופן נחוש. בנה את מודל האיום סביב הקו הזה. סודיות נמצאת בסיסמת המשתמש. הרשאות מעצבות את מה שצופנים מיינסטרים מציעים, וזה הכל
סדר הגדרה: הכל לפני BeginDoc
HotPDF בונה את מילון ההצפנה ומייצר את מפתח הקובץ ברגע שרץ BeginDoc. מה שמאפייני ההגנה מחזיקים באותו רגע הוא מה שהמסמך מקבל, ושינויים לאחר מכן אינם משנים דבר. המאפיין החשוב ביותר כאן הוא CryptKeyLength, שבוחר את הסכמה מתוך ערכי THPDFKeyType: k40, k128, aes128, ו-aes256. הקצה אותו לאחר BeginDoc ולא תקבל חריגה, לא אזהרה — רק קובץ שבשקט שמר על מה שהתחיל בו. סוג סטייה שקטה זה הוא הגרוע מכל: הוא עובר כל בדיקה מקומית ומתגלה חודשים לאחר מכן כממצא תאימות על שולחנו של לקוח
var
Pdf: THotPDF;
begin
Pdf := THotPDF.Create(nil);
try
Pdf.FileName := 'statement.pdf';
Pdf.ActivateProtection := True;
Pdf.CryptKeyLength := aes256; // must be set before BeginDoc
Pdf.UserPassword := 'open-secret';
Pdf.OwnerPassword := 'admin-secret';
Pdf.UseAES256R6 := False; // R=5: widest viewer support
Pdf.BeginDoc;
Pdf.CurrentPage.SetFont('Arial', [], 11);
Pdf.CurrentPage.TextOut(50, 720, 0, 'Account statement, June 2026');
Pdf.EndDoc;
finally
Pdf.Free;
end;
end;
סיסמאות הן UTF-8 ומוגבלות ל-127 בייטים, שהוא מגבלת ISO 32000-2 לסכמות AES-256. אם מדיניות הסיסמאות שלך מספקת סודות ארוכים יותר, בצע את החיתוך בעצמך, בצדך, שם אתה שולט בדיוק היכן החיתוך מתבצע. השאר זאת למקרה והספרייה וצופן עתידי עלולים לא להסכים על נקודת הניתוק, מה שמייצר קובץ שנפתח אצלך ומסרב לאותה סיסמה במקום אחר
גרסה 5 או גרסה 6: בוליאן אחד, שתי מערכות אקולוגיות
UseAES256R6 בוחר בין שתי לחיצות ידיים של AES-256, והבחירה משמעותית יותר ממה שהסוג הבוליאני שלה מרמז. השאר אותה False ו-HotPDF כותב גרסה 5 — סכמת AES-256 שהגיעה כהרחבה ל-PDF 1.7 ושכמו חמש-עשרה שנות צופנים יכולים לפתוח. הגדר אותה ל-True ותקבל גרסה 6 — נגזרת מפתח מוקשחת שהוסדרה ב-ISO 32000-2 עבור PDF 2.0, שסוגרת חולשה ידועה באופן שבו גרסה 5 מאמתת את הסיסמה
לכן גרסה 6 היא הסיפור הקריפטוגרפי הטוב יותר. היא גם זו שמשברת דברים. קובץ גרסה 6 זקוק לצופן שנבנה עבור PDF 1.7 Extension Level 3 או PDF 2.0, ורבות מהתוכנות שנפרסו אינן כאלה: ארכיוני ניהול רשומות, מעבדים מוטמעים במוצרים אחרים, כלים עסקיים שאיש לא נגע בהם שנים. אלה יסרבו לקובץ לחלוטין, ויעשו זאת על מחשב הלקוח, לעולם לא על שלך. ברירת המחדל המעשית היא לכן גרסה 5. הגע לגרסה 6 רק כאשר מדיניות אבטחה מציינת את ISO 32000-2 לפי גרסה, וכאשר אישרת בפועל שכל צרכן יכול לקרוא אותה. כך או כך, רשום איזו בחרת ולמה — כי האדם הבא שייגע בקוד הזה יתהה
סוגי המפתח הישנים ראויים לאזכור כדי שתדע לדלג עליהם. THPDFKeyType עדיין מציג k40, k128, ו-aes128, אך הם קיימים לשחזור ארכיונים היסטוריים, לא להגנה על חדשים. 40-bit RC4 נופל בפני חומרה מסחרית, וסכמות 128-ביט קדמות לגרסאות AES-256 שכל סקירת אבטחה נוכחית תצפה להן. למסמך שאתה יוצר ב-2026 השאלה האמיתית היא רק גרסה 5 מול גרסה 6; אם אתה פונה לסוגים הישנים בעיצוב חדש, משהו במעלה הזרם השתבש
דגלי הרשאות ללא סיסמת פתיחה
לעתים קרובות הדרישה היא הפוך מסודיות. כל אחד צריך להיות מסוגל לקרוא את המסמך, אך הדפסה או חילוץ אמורים להיות מוגבלים. אתה מביע זאת עם סיסמת משתמש ריקה וסיסמת בעלים לא ריקה — ה-PDF מכנה זאת מצב סיסמה פתוחה — ואתה מפרט את הפעולות שברצונך לאפשר ב-ProtectOptions
Pdf.ActivateProtection := True;
Pdf.CryptKeyLength := aes256;
Pdf.UserPassword := ''; // anyone can open the file
Pdf.OwnerPassword := 'rotate-me-quarterly'; // guards the permission set
Pdf.ProtectOptions := [prPrint, prPrint12bit, prExtractContent];
Pdf.BeginDoc;
// ... page content ...
Pdf.EndDoc;
קבוצת THPDFProtectOptions ממפה על ביטי ההרשאה של ISO: prPrint ו-prPrint12bit להדפסה ברזולוציה גבוהה, prInformationCopy להעתקה וחילוץ כלליים, prExtractContent לחילוץ לצרכי טכנולוגיית סיוע, וכן prModifyStructure, prEditAnnotations, prFillAnnotations, ו-prAssemble. שניים מהם ראויים לאזהרה. השאר את prExtractContent פעיל בכמעט כל פרופיל שתבנה. זהו הביט שקורא מסך זקוק לו כדי להגיע לטקסט, וניקוי שקט שלו הופך החלטת זכויות לפגם נגישות שמישהו עם מוגבלות יפגוש ואתה לעולם לא תראה. המלכודת השנייה היא prPrint לבד, ללא prPrint12bit: מספר צופנים מגיבים בהורדת איכות הדפסה, והמשתמשים שלך יגישו זאת כבאג עיבוד ולא כהגדרת ההרשאה שהיא למעשה
אימות לוקח חמש דקות ושייך לרשימת הבדיקה שלך לפני שחרור. פתח דוגמה של כל פרופיל ב-Acrobat, פתח מאפייני מסמך, וקרא את לשונית האבטחה, שמציגה את האלגוריתם ("AES 256-bit") ומפרטת את הפעולות המותרות אחת אחת. לאחר מכן פתח את אותו קובץ בצופן הישן ביותר שהלקוחות שלך מריצים בפועל, לא החדש ביותר על המחשב שלך. הפתיחה השנייה היא ביטוח זול נגד קובץ גרסה 6 שעובר פיתוח ומת אצל לקוח שאף פעם לא שדרג
הסרת הגנה מקבצים קיימים
פענוח הצפנה מריץ את אותו מודל מאפיינים לאחור. טען את המסמך עם אישור תקף, כבה הגנה, ושמור את התוצאה ללא הגנה
var
Pdf: THotPDF;
PageCount: Integer;
begin
Pdf := THotPDF.Create(nil);
try
PageCount := Pdf.LoadFromFile('encrypted.pdf', 'open-secret');
if PageCount > 0 then
begin
Pdf.ActivateProtection := False; // drop encryption on save
Pdf.SaveLoadedDocument('plain.pdf');
end;
finally
Pdf.Free;
end;
end;
נתיב זה מנתח את המסמך כולו לזיכרון, שמתאים לקבצים רגילים ובזבזני לגדולים. כאשר הקלט מגיע למאות מגה-בייטים, DecryptFile הוא האפשרות הזולה יותר: הוא מפענח במהלך העתקה ברמת קובץ, לוקח נתיב כתיבה מחדש ישיר של AES-256 שמדלג על בניית עץ האובייקטים המלא כאשר הקלט מאפשר זאת. הוא חלק מה-Direct File API המכוסה במאמר הנלווה על עיבוד קבצי PDF גדולים מ-Delphi
אילוצים שמתקשרים עם הצפנה
שני מגבלות ראויות לידיעה לפני שתעצב סביב הצפנה ולא אחרי. הראשונה היא תאימות ארכיון. ISO 19005 אוסר הצפנה ב-PDF/A, כך שכל זרימת עבודה שמצפינה מסמך וגם טוענת תאימות PDF/A היא סותרת מבחינת מבנה; HotPDF לא יאפשר לך את שניהם בקובץ אחד. כאשר אתה זקוק לשניהם, התשובה היא שני ארטיפקטים: עותק מוצפן להפצה ועותק נפרד לא מוצפן לארכיון
המגבלה השנייה חדה יותר. להצפנת PDF אין נאמנות ואין שחזור. אבד את סיסמת המשתמש בקובץ R5 או R6 ואפשרויותיך הן כוח גס או ויתור. לכן התייחס לסודות הבעלים והמשתמש כפי שמתייחסים לכל אישור ייצור. צור אותם, אחסן אותם בכספת, רוטד אותם לפי לוח זמנים. הדבר האחד שאסור לעשות הוא לקודד אותם קשיח כקבועים ביחידה, שם הם נוסעים ישירות לבקרת גרסאות ויושבים בכל עותק עבודה של מפתח לנצח
רפלקס אחד נוסף שראוי לבנות. שינוי ההגנה על קובץ שלא יצרת הוא אותו מנגנון כמו פענוח, לא תכונה נפרדת: טעון אותו עם הסיסמה שלו דרך LoadFromFile, ערוך את ProtectOptions או הסיסמאות במקום, וכתוב אותו בחזרה עם SaveLoadedDocument. אם אתה יכול לפענח קובץ, אתה יכול להגדיר מחדש את הרשאותיו, והקוד נראה כמעט זהה לדוגמה לעיל
מאפייני ההגנה המוצגים כאן הם חלק מHotPDF Component הסטנדרטי עבור Delphi ו-C++Builder; דף המוצר נושא את הפניית ההצפנה המלאה, כולל מניין ההרשאות המלא