Μια σημαία δικαιώματος PDF δεν είναι κλειδαριά. Είναι ένα αίτημα που κάνει το αρχείο προς οτιδήποτε το ανοίγει, και ένα πρόγραμμα προβολής είναι ελεύθερο να το αγνοήσει. Αυτό το μοναδικό γεγονός καθορίζει πώς πρέπει να σκέφτεστε για κάθε άλλη επιλογή σε αυτή τη σελίδα. Η πραγματική εμπιστευτικότητα προέρχεται από ένα μόνο σημείο: κρυπτογράφηση AES-256 με κλειδί έναν κωδικό πρόσβασης που δεν διαθέτει ο αναγνώστης. Όλα τα υπόλοιπα, τα πλαίσια επιλογής "no printing" και "no copying", είναι πολιτική που το συμμορφούμενο λογισμικό συμφωνεί να τηρήσει και το εχθρικό λογισμικό όχι. Ανακατέψτε αυτά τα δύο επίπεδα και θα κυκλοφορήσετε κάτι που μοιάζει ασφαλές σε μια επίδειξη και διαρρέει στην πράξη
Το HotPDF είναι ένα εγγενές στοιχείο VCL PDF για Delphi και C++Builder, και εκθέτει το μοντέλο προστασίας ISO 32000 μέσω ενός μικρού συνόλου ιδιοτήτων. Οι ιδιότητες είναι εύκολο να οριστούν. Το δύσκολο κομμάτι είναι να γνωρίζετε ποια σας εξασφαλίζει κρυπτογραφική προστασία και ποια σας εξασφαλίζει απλώς μια ευγενική υπόδειξη, καθώς και να πετύχετε τη σωστή σειρά ανάθεσης ώστε η κρυπτογράφηση που ζητήσατε να είναι όντως η κρυπτογράφηση που θα λάβετε
Τι υπόσχονται στην πραγματικότητα οι δύο κωδικοί πρόσβασης
Η κρυπτογράφηση PDF ορίζει δύο διαπιστευτήρια με διαφορετικούς ρόλους, και η σύγχυσή τους είναι το πιο συνηθισμένο σφάλμα σχεδιασμού σε κώδικα προστατευμένης εξόδου. Ο κωδικός πρόσβασης χρήστη (user password) ελέγχει την αποκρυπτογράφηση. Χωρίς αυτόν, ή τον κωδικό πρόσβασης ιδιοκτήτη (owner password), ένας συμμορφούμενος αναγνώστης δεν μπορεί να ανασυνθέσει το κλειδί αρχείου και το περιεχόμενο παραμένει κρυπτογραφικά μη αναγνώσιμο. Ο κωδικός πρόσβασης ιδιοκτήτη ελέγχει αντίθετα τις ρυθμίσεις δικαιωμάτων: ένας αναγνώστης που λαμβάνει τον κωδικό πρόσβασης ιδιοκτήτη αποκτά πλήρη πρόσβαση ανεξάρτητα από το τι λένε οι σημαίες περιορισμού
Τα bit δικαιωμάτων στέκονται σε πιο αδύναμο έδαφος. Εκτύπωση, εξαγωγή περιεχομένου, συμπλήρωση φόρμας: το καθένα είναι μια σημαία που ένα πρόγραμμα προβολής διαβάζει και επιλέγει αν θα τη σεβαστεί (ISO 32000-2 §7.6.4). Η κρυπτογράφηση προστατεύει τα bytes. Οι σημαίες δικαιωμάτων απλώς καθοδηγούν το συμμορφούμενο λογισμικό, και το καθοδηγούν εκ των υστέρων. Όποιος ανοίξει το έγγραφο με τον κωδικό πρόσβασης χρήστη κατέχει ήδη το αποκρυπτογραφημένο περιεχόμενο στη μνήμη, οπότε το "no copy" και το "no print" σημαίνουν κάτι για ένα καλά συμπεριφερόμενο πρόγραμμα προβολής και τίποτα για ένα αποφασισμένο. Χτίστε το μοντέλο απειλής γύρω από αυτή τη γραμμή. Η εμπιστευτικότητα κατοικεί στον κωδικό πρόσβασης χρήστη. Τα δικαιώματα διαμορφώνουν αυτό που προσφέρουν τα κύρια προγράμματα προβολής, και αυτό είναι το σύνολο όσων κάνουν
Σειρά διαμόρφωσης: όλα πριν το 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; // πρέπει να οριστεί πριν το BeginDoc
Pdf.UserPassword := 'open-secret';
Pdf.OwnerPassword := 'admin-secret';
Pdf.UseAES256R6 := False; // R=5: ευρύτερη υποστήριξη προγραμμάτων προβολής
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 bytes, που είναι το όριο του ISO 32000-2 για τα σχήματα AES-256. Αν η πολιτική κωδικών πρόσβασής σας σάς δίνει μεγαλύτερα μυστικά, κάντε την περικοπή εσείς οι ίδιοι, στη δική σας πλευρά, όπου ελέγχετε ακριβώς πού πέφτει η τομή. Αφήστε το στην τύχη και η βιβλιοθήκη με κάποιο μελλοντικό πρόγραμμα προβολής μπορεί να διαφωνήσουν για το σημείο περικοπής, κάτι που παράγει ένα αρχείο που ανοίγει σε εσάς και απορρίπτει τον ίδιο κωδικό πρόσβασης κάπου αλλού
Revision 5 ή revision 6: ένα boolean, δύο οικοσυστήματα
Το UseAES256R6 επιλέγει ανάμεσα στις δύο χειραψίες AES-256, και η επιλογή έχει μεγαλύτερες συνέπειες από όσες υποδηλώνει ο τύπος boolean. Αφήστε το False και το HotPDF γράφει revision 5, το σχήμα AES-256 που ήρθε ως επέκταση στο PDF 1.7 και που μπορούν να ανοίξουν προγράμματα προβολής περίπου δεκαπέντε ετών. Ορίστε το True και λαμβάνετε revision 6, την ενισχυμένη παραγωγή κλειδιού που τυποποιήθηκε στο ISO 32000-2 για το PDF 2.0, η οποία κλείνει μια γνωστή αδυναμία στον τρόπο που η revision 5 επαληθεύει τον κωδικό πρόσβασης
Άρα η revision 6 είναι κρυπτογραφικά η καλύτερη επιλογή. Είναι όμως και αυτή που χαλάει πράγματα. Ένα αρχείο revision 6 χρειάζεται πρόγραμμα προβολής χτισμένο για PDF 1.7 Extension Level 3 ή PDF 2.0, και πολύ αναπτυγμένο λογισμικό δεν είναι τίποτα από τα δύο: αρχεία διαχείρισης εγγράφων, ενσωματωμένοι renderers σε άλλα προϊόντα, εργαλεία επιχειρησιακής λειτουργίας που κανείς δεν έχει αγγίξει εδώ και χρόνια. Αυτά θα απορρίψουν το αρχείο εντελώς, και θα το κάνουν στον υπολογιστή του πελάτη, ποτέ στον δικό σας. Η πρακτική προεπιλογή είναι επομένως η revision 5. Καταφύγετε στη revision 6 μόνο όταν μια πολιτική ασφαλείας κατονομάζει το ISO 32000-2 κατά revision, και όταν έχετε πράγματι επιβεβαιώσει ότι κάθε παραλήπτης μπορεί να το διαβάσει. Όποια κι αν είναι η επιλογή, καταγράψτε ποια διαλέξατε και γιατί, επειδή ο επόμενος που θα αγγίξει αυτόν τον κώδικα θα αναρωτηθεί
Οι παλαιότεροι τύποι κλειδιών αξίζουν μια πρόταση ώστε να ξέρετε να τους παραλείψετε. Το THPDFKeyType εξακολουθεί να παραθέτει τα k40, k128 και aes128, αλλά υπάρχουν για την αναπαραγωγή ιστορικών αρχείων, όχι για την προστασία νέων. Το RC4 40-bit υποκύπτει σε κοινό υλικό, και τα σχήματα 128-bit προηγούνται των revisions AES-256 που θα αναμένει κάθε σύγχρονη αναθεώρηση ασφαλείας. Για ένα έγγραφο που δημιουργείτε το 2026 το πραγματικό ερώτημα είναι μόνο revision 5 έναντι revision 6· αν βρεθείτε να καταφεύγετε στους παλαιότερους τύπους σε έναν νέο σχεδιασμό, κάτι έχει πάει στραβά νωρίτερα στη ροή
Σημαίες δικαιωμάτων χωρίς κωδικό πρόσβασης ανοίγματος
Συχνά η απαίτηση είναι το αντίθετο της μυστικότητας. Οποιοσδήποτε πρέπει να μπορεί να διαβάσει το έγγραφο, αλλά η εκτύπωση ή η εξαγωγή προορίζεται να είναι περιορισμένη. Αυτό εκφράζεται με έναν κενό κωδικό πρόσβασης χρήστη και έναν μη κενό κωδικό πρόσβασης ιδιοκτήτη, κάτι που το PDF ονομάζει λειτουργία ανοιχτού κωδικού πρόσβασης (open-password mode), και παραθέτετε τις λειτουργίες που θέλετε να επιτρέψετε στο ProtectOptions
Pdf.ActivateProtection := True;
Pdf.CryptKeyLength := aes256;
Pdf.UserPassword := ''; // οποιοσδήποτε μπορεί να ανοίξει το αρχείο
Pdf.OwnerPassword := 'rotate-me-quarterly'; // προστατεύει το σύνολο δικαιωμάτων
Pdf.ProtectOptions := [prPrint, prPrint12bit, prExtractContent];
Pdf.BeginDoc;
// ... περιεχόμενο σελίδας ...
Pdf.EndDoc;
Το σύνολο THPDFProtectOptions αντιστοιχίζεται στα bit δικαιωμάτων ISO: τα prPrint και prPrint12bit για εκτύπωση υψηλής ανάλυσης, το prInformationCopy για γενική αντιγραφή και εξαγωγή, το prExtractContent για εξαγωγή τεχνολογίας υποβοήθησης, συν τα prModifyStructure, prEditAnnotations, prFillAnnotations και prAssemble. Δύο από αυτά αξίζουν μια προειδοποίηση. Αφήστε το prExtractContent ενεργό σχεδόν σε κάθε προφίλ που χτίζετε. Είναι το bit που χρειάζεται ένας screen reader για να φτάσει στο κείμενο, και η απενεργοποίησή του μετατρέπει σιωπηλά μια απόφαση δικαιωμάτων σε ελάττωμα προσβασιμότητας που κάποιος με αναπηρία θα συναντήσει και εσείς ποτέ δεν θα δείτε. Η άλλη παγίδα είναι το prPrint μόνο του, χωρίς το prPrint12bit: αρκετά προγράμματα προβολής αντιδρούν υποβαθμίζοντας την ποιότητα εκτύπωσης, και οι χρήστες σας θα το καταγράψουν ως σφάλμα απόδοσης αντί για τη ρύθμιση δικαιωμάτων που στην πραγματικότητα είναι
Η επαλήθευση διαρκεί πέντε λεπτά και ανήκει στη λίστα ελέγχου κυκλοφορίας σας. Ανοίξτε ένα δείγμα κάθε προφίλ στο Acrobat, ανοίξτε το Document Properties, και διαβάστε την καρτέλα Security, η οποία αναφέρει ρητά τον αλγόριθμο ("AES 256-bit") και παραθέτει τις επιτρεπόμενες λειτουργίες μία προς μία. Στη συνέχεια ανοίξτε το ίδιο αρχείο στο παλαιότερο πρόγραμμα προβολής που πράγματι χρησιμοποιούν οι πελάτες σας, όχι στο νεότερο που έχετε στον δικό σας υπολογιστή. Αυτό το δεύτερο άνοιγμα είναι η φθηνή ασφάλιση απέναντι σε ένα αρχείο revision 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; // αφαίρεση κρυπτογράφησης κατά την αποθήκευση
Pdf.SaveLoadedDocument('plain.pdf');
end;
finally
Pdf.Free;
end;
end;
Αυτή η διαδρομή αναλύει ολόκληρο το έγγραφο στη μνήμη, κάτι που είναι μια χαρά για συνηθισμένα αρχεία και σπάταλο για τεράστια. Όταν η είσοδος φτάνει σε εκατοντάδες megabyte, το DecryptFile είναι η φθηνότερη επιλογή: αποκρυπτογραφεί κατά τη διάρκεια ενός αντιγράφου σε επίπεδο αρχείου, ακολουθώντας μια απευθείας διαδρομή επανεγγραφής AES-256 που παρακάμπτει τη δημιουργία ολόκληρου του δέντρου αντικειμένων όποτε το επιτρέπει η είσοδος. Αποτελεί μέρος του Direct File API που καλύπτεται στο συνοδευτικό άρθρο για την επεξεργασία μεγάλων PDF από το Delphi
Περιορισμοί που αλληλεπιδρούν με την κρυπτογράφηση
Αξίζει να γνωρίζετε δύο περιορισμούς προτού σχεδιάσετε γύρω από την κρυπτογράφηση και όχι μετά. Ο πρώτος είναι η συμμόρφωση αρχειοθέτησης. Το ISO 19005 απαγορεύει την κρυπτογράφηση στο PDF/A, οπότε κάθε ροή εργασίας που κρυπτογραφεί ένα έγγραφο και ταυτόχρονα διεκδικεί συμμόρφωση PDF/A είναι αντιφατική εκ κατασκευής· το HotPDF δεν σας επιτρέπει να έχετε και τα δύο σε ένα αρχείο. Όταν πράγματι χρειάζεστε και τα δύο, η απάντηση είναι δύο τεχνουργήματα (artifacts): ένα κρυπτογραφημένο αντίγραφο για διανομή και ένα ξεχωριστό μη κρυπτογραφημένο αντίγραφο για το αρχείο
Ο δεύτερος περιορισμός είναι πιο αυστηρός. Η κρυπτογράφηση PDF δεν διαθέτει ούτε θεματοφυλακή (escrow) ούτε ανάκτηση. Χάστε τον κωδικό πρόσβασης χρήστη σε ένα αρχείο R5 ή R6 και οι επιλογές σας είναι brute force ή εγκατάλειψη. Αντιμετωπίστε λοιπόν τα μυστικά ιδιοκτήτη και χρήστη όπως αντιμετωπίζετε κάθε διαπιστευτήριο παραγωγής. Δημιουργήστε τα, αποθηκεύστε τα σε ένα vault, εναλλάξτε τα σε πρόγραμμα. Το ένα πράγμα που δεν πρέπει ποτέ να κάνετε είναι να τα κωδικοποιήσετε ως σταθερές μέσα σε μια unit, όπου ταξιδεύουν κατευθείαν στο version control και παραμένουν στο working copy κάθε προγραμματιστή για πάντα
Ένα τελευταίο αντανακλαστικό αξίζει να αναπτυχθεί. Η αλλαγή της προστασίας σε ένα αρχείο που δεν δημιουργήσατε εσείς είναι ο ίδιος μηχανισμός με την αποκρυπτογράφηση, όχι ξεχωριστό χαρακτηριστικό: φορτώστε το με τον κωδικό πρόσβασής του μέσω LoadFromFile, επεξεργαστείτε το ProtectOptions ή τους κωδικούς πρόσβασης επιτόπου, και γράψτε το πίσω με το SaveLoadedDocument. Αν μπορείτε να αποκρυπτογραφήσετε ένα αρχείο, μπορείτε και να αλλάξετε τα δικαιώματά του, και ο κώδικας μοιάζει σχεδόν πανομοιότυπος με το παράδειγμα παραπάνω
Οι ιδιότητες προστασίας που παρουσιάζονται εδώ αποτελούν μέρος του τυπικού HotPDF Delphi Component για Delphi και C++Builder· η σελίδα προϊόντος διαθέτει την πλήρη αναφορά κρυπτογράφησης, συμπεριλαμβανομένης της πλήρους απαρίθμησης δικαιωμάτων