Πώς να εργαστείτε με τη μηχανή κρυπτογράφησης PDF στο Python
Aspose.PDF FOSS για Python (import aspose_pdf) υλοποιεί την προστασία κωδικού PDF σε επίπεδο byte μέσω μιας μικρής εσωτερικής κλάσης μηχανής, EncryptionUtils, στο aspose_pdf.engine.encryption. Εδώ κατοικούν ο αλγόριθμος κρυπτογράφησης AES-CBC και οι αλγόριθμοι παραγωγής κλειδιών του PDF Standard Security Handler (ISO 32000 Εκδόσεις 2 έως 6), ανεξάρτητα από το υψηλού επιπέδου Document API. Αυτός ο οδηγός εγκαθιστά το πακέτο και περιγράφει τρεις εργασίες της μηχανής: κρυπτογράφηση και αποκρυπτογράφηση ακατέργαστων bytes με AES-CBC, παραγωγή κλειδιών Standard Security Handler για έναν κωδικό (Εκδόσεις 2-4), και παραγωγή κλειδιών AES-256 για έγγραφα Έκδοσης 5/6.
Οδηγός βήμα-βήμα
Βήμα 2: Εισαγωγή των Απαιτούμενων Κλάσεων
EncryptionUtils δεν εξάγεται ξανά από το κορυφαίο πακέτο aspose_pdf — εισάγετέ το απευθείας από το υπο-μονάδα engine.encryption:
import os
from aspose_pdf.engine.encryption import EncryptionUtilsΒήμα 3: Κρυπτογράφηση και Αποκρυπτογράφηση Δεδομένων με AES-CBC
encrypt_aes_cbc και decrypt_aes_cbc λειτουργούν απευθείας με οποιοδήποτε κλειδί 16-, 24- ή 32- byte (AES-128, AES-192 ή AES-256) χωρίς να περνούν από παραγωγή κλειδιού βάσει κωδικού. encrypt_aes_cbc εφαρμόζει εσωτερικά padding PKCS7, και decrypt_aes_cbc το αφαιρεί.
key = os.urandom(32) # AES-256; 16- and 24-byte keys are also accepted
plaintext = b"Confidential PDF content"
ciphertext = EncryptionUtils.encrypt_aes_cbc(key, plaintext)
decrypted = EncryptionUtils.decrypt_aes_cbc(key, ciphertext)
assert decrypted == plaintext
print("Roundtrip OK, ciphertext length:", len(ciphertext))Βήμα 4: Προεξαγωγή Κλειδιών Τυπικού Διαχειριστή Ασφαλείας για Κωδικό Πρόσβασης (Αναθεωρήσεις 2-4)
compute_owner_key_v4 υπολογίζει την τιμή του κωδικού ιδιοκτήτη (O) σύμφωνα με τον Αλγόριθμο 3.3, και compute_user_key_v4 υπολογίζει την τιμή του κωδικού χρήστη (U) και το κλειδί κρυπτογράφησης του αρχείου σύμφωνα με τους Αλγόριθμους 3.4/3.5. verify_password_v4 επαναπροκαλεί το κλειδί από έναν υποψήφιο κωδικό ώστε να μπορείτε να επιβεβαιώσετε ότι ανοίγει το έγγραφο πριν το εμπιστευτείτε.
owner_password = "owner-secret"
user_password = "user-secret"
key_length = 16 # 128-bit (AES/RC4); Revision 2 uses 5 (40-bit)
revision = 4
file_id = os.urandom(16)
permissions = -4 # standard PDF permissions value
o_value = EncryptionUtils.compute_owner_key_v4(
owner_password, user_password, key_length, revision
)
u_value, encryption_key = EncryptionUtils.compute_user_key_v4(
user_password, o_value, permissions, file_id, key_length, revision
)
verified_key = EncryptionUtils.verify_password_v4(
user_password, u_value, o_value, permissions, file_id, key_length, revision
)
assert verified_key == encryption_key
ciphertext = EncryptionUtils.encrypt_aes_cbc(verified_key, b"Confidential PDF content")
decrypted = EncryptionUtils.decrypt_aes_cbc(verified_key, ciphertext)
assert decrypted == b"Confidential PDF content"o_value και u_value είναι πάντα 32 byte ανεξάρτητα από το key_length. verify_password_v4 επιστρέφει None — όχι μια εξαίρεση — όταν ο κωδικός δεν ταιριάζει.
Βήμα 5: Προεξαγωγή Κλειδιών AES-256 για Έγγραφα Αναθεώρησης 5/6
Οι διαχειριστές ασφαλείας Αναθεώρησης 5 και 6 (AES-256) δεν χρησιμοποιούν compute_owner_key_v4/compute_user_key_v4 — εφαρμόζουν κατακερματισμό του κωδικού με compute_hash_v5, που υλοποιεί τον «Αλγόριθμο 2.B» του ISO 32000-2. Χρησιμοποιήστε generate_file_id για ένα νέο αναγνωριστικό αρχείου και derive_object_key για να μετατρέψετε ένα κλειδί κρυπτογράφησης αρχείου σε κλειδί για ένα συγκεκριμένο έμμεσο αντικείμενο.
password = b"SecurePassword123"
salt = os.urandom(8)
password_hash = EncryptionUtils.compute_hash_v5(password, salt)
assert len(password_hash) == 32
file_id = EncryptionUtils.generate_file_id()
assert len(file_id) == 16
file_key = os.urandom(32)
object_key = EncryptionUtils.derive_object_key(file_key, 12, 0, use_aes=True)
assert len(object_key) == 16derive_object_key αναμειγνύει τον αριθμό αντικειμένου και τον αριθμό γενιάς στο κλειδί αρχείου, έτσι ώστε κάθε έμμεσο αντικείμενο να παίρνει το δικό του κλειδί παρόλο που το κλειδί αρχείου μοιράζεται.
Κοινά Προβλήματα και Διορθώσεις
encrypt_aes_cbc/decrypt_aes_cbc εμφανίζει “AES key must be 16, 24, or 32 bytes”. Το όρισμα key πρέπει να είναι ένα πραγματικό κλειδί AES, όχι μια ακατέργαστη συμβολοσειρά κωδικού πρόσβασης. Δημιουργήστε ένα με os.urandom(16 | 24 | 32), ή προεξάγετε ένα πρώτα με compute_user_key_v4 (Αναθεωρήσεις 2-4) ή compute_hash_v5 (Αναθεωρήσεις 5/6).
verify_password_v4 returns None αντί για την εμφάνιση. Αυτό σημαίνει ότι ο κωδικός πρόσβασης δεν ταιριάζει — δεν είναι κατάσταση σφάλματος που πρέπει να πιαστεί, αλλά ένα αποτέλεσμα που πρέπει να ελεγχθεί. Επίσης επιβεβαιώστε ότι permissions, file_id, key_length, και revision είναι ακριβώς οι ίδιες τιμές που χρησιμοποιούνται όταν το έγγραφο o_value and u_value υπολογίστηκαν αρχικά· μια ασυμφωνία σε οποιοδήποτε από αυτά παράγει σιωπηρά το λάθος κλειδί αντί να αποτύχει έντονα.
compute_owner_key_v4 με κενό κωδικό ιδιοκτήτη. Passing "" for owner_password είναι συμπεριφορά που ορίζεται από την προδιαγραφή, όχι σφάλμα — ο αλγόριθμος επιστρέφει στη χρήση του κωδικού χρήστη, έτσι οι κωδικοί ιδιοκτήτη και χρήστη γίνονται ισοδύναμοι.
Κλειδιά που προέρχονται από λάθος έκδοση ή μήκος κλειδιού. Η Έκδοση 2 χρησιμοποιεί κλειδιά RC4 40-bit (5-byte), οι Εκδόσεις 3/4 χρησιμοποιούν κλειδιά RC4/AES 128-bit (16-byte), και οι Εκδόσεις 5/6 χρησιμοποιούν compute_hash_v5 αντί για compute_owner_key_v4/compute_user_key_v4 εντελώς. Η ανάμειξη αυτών δεν προκαλεί εξαίρεση — δημιουργεί απλώς ένα κλειδί που δεν θα ανοίξει το έγγραφο.
compute_hash_v5 η έξοδος αλλάζει απροσδόκητα. Το τρίτο όρισμα (user_key) είναι μιγμένο στον κατακερματισμό. Περνάτε b"" ρητά όταν θέλετε έναν απλό κατακερματισμό επαλήθευσης κωδικού, επειδή η παράλειψή του δεν είναι το ίδιο με τη μεταβίβαση μιας κενής τιμής σε κάθε σημείο κλήσης.
Συχνές Ερωτήσεις
Γιατί το EncryptionUtils δεν είναι importable απευθείας από το aspose_pdf;
Βρίσκεται στο υποπακέτο engine επειδή είναι μια εσωτερική λεπτομέρεια υλοποίησης της προστασίας κωδικού σε επίπεδο εγγράφου, όχι μέρος της υψηλού επιπέδου δημόσιας επιφάνειας API. Εισάγετε το ρητά από το aspose_pdf.engine.encryption.
Είναι το compute_hash_v5 το ίδιο με μια μόνο κλήση SHA-256;
Όχι. Υλοποιεί τον Αλγόριθμο 2.B του ISO 32000-2, ο οποίος εκτελεί πολλαπλούς γύρους χρησιμοποιώντας διαφορετικούς αλγόριθμους hash που επιλέγονται από ενδιάμεσες τιμές — σκόπιμα πιο ακριβό από μια ενιαία κλήση hash.
Επιστρέφει το generate_file_id() τα ίδια bytes κάθε φορά;
Όχι — επιστρέφει μια νέα, τυχαία τιμή 16-byte σε κάθε κλήση. Ένα διαφορετικό αναγνωριστικό αρχείου αλλάζει κάθε κλειδί που προκύπτει από αυτό, ακόμη και όταν ο κωδικός πρόσβασης είναι ταυτόσιος.
Μοιράζονται όλα τα έμμεσα αντικείμενα σε ένα κρυπτογραφημένο PDF ένα κλειδί;
Όχι. Το derive_object_key συνδυάζει τον αριθμό αντικειμένου και τον αριθμό γενιάς με το κλειδί κρυπτογράφησης αρχείου, έτσι ώστε κάθε έμμεσο αντικείμενο να λαμβάνει ένα διακριτό κλειδί ανά αντικείμενο.
Θα πρέπει ο κώδικας εφαρμογής να καλεί το EncryptionUtils άμεσα για την προστασία ενός PDF με κωδικό πρόσβασης;
Συνήθως όχι. Το EncryptionUtils είναι η μηχανή χαμηλού επιπέδου πάνω στην οποία χτίζονται τα API κωδικού πρόσβασης επιπέδου εγγράφου. Οι περισσότερες εφαρμογές πρέπει να προστατεύουν τα PDF μέσω του API επιπέδου εγγράφου και να χρησιμοποιούν το EncryptionUtils μόνο για προσαρμοσμένα εργαλεία ή δικανική επιθεώρηση κρυπτογραφημένων αρχείων.