कैसे काम करें PDF एन्क्रिप्शन इंजन के साथ Python में

कैसे काम करें PDF एन्क्रिप्शन इंजन के साथ Python में

Aspose.PDF FOSS for Python (import aspose_pdf) बाइट स्तर पर एक छोटे आंतरिक इंजन क्लास, EncryptionUtils, के माध्यम से PDF पासवर्ड सुरक्षा लागू करता है, जो aspose_pdf.engine.encryption में है। यहाँ AES-CBC सिफर और PDF स्टैंडर्ड सिक्योरिटी हैंडलर के कुंजी-उत्पन्न एल्गोरिदम (ISO 32000 रिवीजन 2 से 6) स्थित हैं, जो उच्च-स्तरीय Document API से स्वतंत्र हैं। यह गाइड पैकेज स्थापित करता है और तीन इंजन कार्यों को चरणबद्ध रूप से दर्शाता है: AES-CBC के साथ कच्चे बाइट्स को एन्क्रिप्ट और डिक्रिप्ट करना, पासवर्ड के लिए स्टैंडर्ड सिक्योरिटी हैंडलर कुंजियों को उत्पन्न करना (रिवीजन 2-4), और रिवीजन 5/6 दस्तावेज़ों के लिए AES-256 कुंजियों को उत्पन्न करना।

चरण-दर-चरण मार्गदर्शिका

चरण 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-बाइट कुंजी (AES-128, AES-192, या AES-256) पर काम करते हैं, बिना पासवर्ड-आधारित कुंजी उत्पन्न प्रक्रिया के। encrypt_aes_cbc आंतरिक रूप से 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 एल्गोरिदम 3.3 के अनुसार ओनर पासवर्ड मान (O) की गणना करता है, और compute_user_key_v4 एल्गोरिदम 3.4/3.5 के अनुसार यूज़र पासवर्ड मान (U) और फ़ाइल एन्क्रिप्शन कुंजी की गणना करता है। 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 बाइट्स होते हैं, चाहे key_length कुछ भी हो। verify_password_v4 None लौटाता है — यह कोई अपवाद नहीं है — जब पासवर्ड मेल नहीं खाता।


चरण 5: संस्करण 5/6 दस्तावेज़ों के लिए AES-256 कुंजियों को व्युत्पन्न करें

संस्करण 5 और 6 सुरक्षा हैंडलर (AES-256) compute_owner_key_v4/compute_user_key_v4 का उपयोग नहीं करते — वे पासवर्ड को compute_hash_v5 के साथ हैश करते हैं, जो ISO 32000-2 के “Algorithm 2.B” को लागू करता है। एक नया फ़ाइल पहचानकर्ता के लिए 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) == 16

derive_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 (Revisions 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 40-बिट (5-बाइट) RC4 कुंजियों का उपयोग करता है, संस्करण 3/4 128-बिट (16-बाइट) RC4/AES कुंजियों का उपयोग करते हैं, और संस्करण 5/6 उपयोग करते हैं compute_hash_v5 के बजाय compute_owner_key_v4/compute_user_key_v4 पूरी तरह से। इनका मिश्रण अपवाद नहीं उठाता — यह केवल एक ऐसी कुंजी उत्पन्न करता है जो दस्तावेज़ को नहीं खोल पाएगी।

compute_hash_v5 आउटपुट अप्रत्याशित रूप से बदलता है। तीसरा तर्क (user_key) हैश में मिश्रित। पास करें b"" स्पष्ट रूप से जब आप एक साधारण पासवर्ड-वैधता हैश चाहते हैं, क्योंकि इसे छोड़ देना हर कॉल साइट में खाली मान पास करने के बराबर नहीं है।


अक्सर पूछे जाने वाले प्रश्न

क्यों EncryptionUtils को aspose_pdf से सीधे आयात नहीं किया जा सकता?

यह engine सबपैकेज में रहता है क्योंकि यह दस्तावेज़-स्तर पासवर्ड सुरक्षा का एक आंतरिक कार्यान्वयन विवरण है, उच्च-स्तरीय सार्वजनिक API सतह का हिस्सा नहीं है। इसे स्पष्ट रूप से aspose_pdf.engine.encryption से आयात करें।

क्या compute_hash_v5 एकल SHA-256 कॉल के समान है?

नहीं। यह ISO 32000-2 के एल्गोरिथ्म 2.B को लागू करता है, जो मध्यवर्ती मानों द्वारा चयनित विभिन्न हैश एल्गोरिदम का उपयोग करके कई राउंड करता है — एकल हैश कॉल की तुलना में इरादतन अधिक महंगा।

क्या generate_file_id() हर बार एक ही बाइट्स लौटाता है?

नहीं — यह हर कॉल पर एक नया, रैन्डम 16-बाइट मान लौटाता है। एक अलग फ़ाइल पहचानकर्ता उससे निकाली गई हर कुंजी को बदल देता है, भले ही पासवर्ड समान हो।

क्या एन्क्रिप्टेड PDF में सभी इंडायरेक्ट ऑब्जेक्ट्स एक ही कुंजी साझा करते हैं?

नहीं। derive_object_key ऑब्जेक्ट नंबर और जनरेशन नंबर को फ़ाइल एन्क्रिप्शन कुंजी के साथ मिलाता है, इसलिए प्रत्येक इंडायरेक्ट ऑब्जेक्ट को एक विशिष्ट प्रति-ऑब्जेक्ट कुंजी मिलती है।

क्या एप्लिकेशन कोड को PDF को पासवर्ड-प्रोटेक्ट करने के लिए सीधे EncryptionUtils को कॉल करना चाहिए?

आमतौर पर नहीं। EncryptionUtils वह लो-लेवल इंजन है जिस पर दस्तावेज-स्तर के पासवर्ड API बनाए गए हैं। अधिकांश एप्लिकेशन को PDF को दस्तावेज-स्तर के API के माध्यम से सुरक्षित करना चाहिए और EncryptionUtils को केवल कस्टम टूलिंग या एन्क्रिप्टेड फ़ाइलों की फोरेंसिक जांच के लिए ही उपयोग करना चाहिए।


यह भी देखें

 हिन्दी