Python Language
सुरक्षा और क्रिप्टोग्राफी
खोज…
परिचय
पायथन, कंप्यूटर और नेटवर्क सुरक्षा में सबसे लोकप्रिय भाषाओं में से एक होने के नाते, सुरक्षा और क्रिप्टोग्राफी में काफी संभावनाएं हैं। यह विषय पाइथन में क्रिप्टोग्राफिक विशेषताओं और कार्यान्वयन से लेकर कंप्यूटर और नेटवर्क सुरक्षा में हैशिंग और एन्क्रिप्शन / डिक्रिप्शन एल्गोरिदम तक के उपयोग से संबंधित है।
वाक्य - विन्यास
- hashlib.new (नाम)
- hashlib.pbkdf2_hmac (नाम, पासवर्ड, नमक, गोल, dklen = कोई नहीं)
टिप्पणियों
hashlib
में कई तरीकों से आपको स्ट्रिंग के बजाय बाइट्स के बफ़र के रूप में व्याख्या करने योग्य मूल्यों को पारित करने की आवश्यकता होगी। यह hashlib.new().update()
साथ-साथ hashlib.pbkdf2_hmac
। यदि आपके पास एक स्ट्रिंग है, तो आप इसे स्ट्रिंग की शुरुआत के लिए चरित्र b
को प्रीपे करके बाइट बफर में बदल सकते हैं:
"This is a string"
b"This is a buffer of bytes"
एक संदेश डाइजेस्ट की गणना
hashlib
मॉड्यूल new
विधि के माध्यम से संदेश डाइजेस्ट जनरेटर बनाने की अनुमति देता है। ये जनरेटर एक मनमाना स्ट्रिंग को एक निश्चित लंबाई के पाचन में बदल देंगे:
import hashlib
h = hashlib.new('sha256')
h.update(b'Nobody expects the Spanish Inquisition.')
h.digest()
# ==> b'.\xdf\xda\xdaVR[\x12\x90\xff\x16\xfb\x17D\xcf\xb4\x82\xdd)\x14\xff\xbc\xb6Iy\x0c\x0eX\x9eF-='
ध्यान दें कि आप कॉल कर सकते हैं update
कॉल करने से पहले कई बार एक मनमाना संख्या digest
जो हैश को हिस्सा द्वारा एक बड़ी फ़ाइल हिस्सा उपयोगी है। आप हेक्साडेसिमल फॉर्मेट का उपयोग करके hexdigest
को हेक्साडेसिमल फॉर्मेट में प्राप्त कर सकते हैं:
h.hexdigest()
# ==> '2edfdada56525b1290ff16fb1744cfb482dd2914ffbcb649790c0e589e462d3d'
उपलब्ध हैशिंग एल्गोरिदम
जब आप जनरेटर का उत्पादन करने के लिए कहते हैं, तो hashlib.new
को एक एल्गोरिथ्म के नाम की आवश्यकता होती है। वर्तमान पायथन इंटरप्रेटर में कौन से एल्गोरिदम उपलब्ध हैं, यह hashlib.algorithms_available
लिए, hashlib.algorithms_available
उपयोग hashlib.algorithms_available
:
import hashlib
hashlib.algorithms_available
# ==> {'sha256', 'DSA-SHA', 'SHA512', 'SHA224', 'dsaWithSHA', 'SHA', 'RIPEMD160', 'ecdsa-with-SHA1', 'sha1', 'SHA384', 'md5', 'SHA1', 'MD5', 'MD4', 'SHA256', 'sha384', 'md4', 'ripemd160', 'sha224', 'sha512', 'DSA', 'dsaEncryption', 'sha', 'whirlpool'}
प्लेटफ़ॉर्म और दुभाषिया के अनुसार लौटी सूची अलग-अलग होगी; सुनिश्चित करें कि आप अपने एल्गोरिथ्म उपलब्ध है की जाँच करें।
कुछ एल्गोरिदम भी हैं जो सभी प्लेटफार्मों और दुभाषियों पर उपलब्ध होने की गारंटी है, जो hashlib.algorithms_guaranteed
का उपयोग करके उपलब्ध हैं:
hashlib.algorithms_guaranteed
# ==> {'sha256', 'sha384', 'sha1', 'sha224', 'md5', 'sha512'}
सुरक्षित पासवर्ड हैशिंग
hashlib
मॉड्यूल द्वारा उजागर PBKDF2 एल्गोरिथ्म का उपयोग सुरक्षित पासवर्ड हैशिंग करने के लिए किया जा सकता है। हालांकि यह एल्गोरिथम संग्रहित हैश से मूल पासवर्ड को पुनर्प्राप्त करने के लिए जानवर के बल के हमलों को रोक नहीं सकता है, लेकिन यह ऐसे हमलों को बहुत महंगा बनाता है।
import hashlib
import os
salt = os.urandom(16)
hash = hashlib.pbkdf2_hmac('sha256', b'password', salt, 100000)
PBKDF2 किसी भी डाइजेस्ट एल्गोरिथ्म के साथ काम कर सकता है, उपरोक्त उदाहरण SHA256 का उपयोग करता है जिसे आमतौर पर अनुशंसित किया जाता है। यादृच्छिक नमक को हैशेड पासवर्ड के साथ संग्रहीत किया जाना चाहिए, आपको संग्रहीत हैश में दर्ज पासवर्ड की तुलना करने के लिए फिर से इसकी आवश्यकता होगी। यह आवश्यक है कि प्रत्येक पासवर्ड एक अलग नमक के साथ हैशेड हो। राउंड की संख्या के रूप में, यह आपके आवेदन के लिए जितना संभव हो उतना उच्च सेट करने के लिए अनुशंसित है।
यदि आप हेक्साडेसिमल में परिणाम चाहते हैं, तो आप binascii
मॉड्यूल का उपयोग कर सकते हैं:
import binascii
hexhash = binascii.hexlify(hash)
नोट : जबकि PBKDF2 बुरा नहीं है, bcrypt और विशेष रूप से scrypt को brute-force attack के खिलाफ अधिक मजबूत माना जाता है। न ही फिलहाल पायथन मानक पुस्तकालय का हिस्सा है।
फ़ाइल हाशिंग
एक हैश एक फ़ंक्शन है जो बाइट्स के एक चर लंबाई अनुक्रम को एक निश्चित लंबाई अनुक्रम में परिवर्तित करता है। कई कारणों से फाइल को हैक करना फायदेमंद हो सकता है। यह जांचने के लिए कि क्या दो फाइलें एक जैसी हैं या सत्यापित की जा रही हैं कि फाइल की सामग्री दूषित या बदली नहीं गई है, तो उसका उपयोग किया जा सकता है।
किसी फ़ाइल के लिए हैश उत्पन्न करने के लिए आप hashlib
का उपयोग कर सकते हैं:
import hashlib
hasher = hashlib.new('sha256')
with open('myfile', 'r') as f:
contents = f.read()
hasher.update(contents)
print hasher.hexdigest()
बड़ी फ़ाइलों के लिए, निश्चित लंबाई के एक बफर का उपयोग किया जा सकता है:
import hashlib
SIZE = 65536
hasher = hashlib.new('sha256')
with open('myfile', 'r') as f:
buffer = f.read(SIZE)
while len(buffer) > 0:
hasher.update(buffer)
buffer = f.read(SIZE)
print(hasher.hexdigest())
Pycrypto का उपयोग करके सममित एन्क्रिप्शन
पायथन की अंतर्निहित क्रिप्टो कार्यक्षमता वर्तमान में हैशिंग तक सीमित है। एन्क्रिप्शन को pycrypto जैसे थर्ड-पार्टी मॉड्यूल की आवश्यकता होती है। उदाहरण के लिए, यह एईएस एल्गोरिथ्म प्रदान करता है जिसे सममित एन्क्रिप्शन के लिए कला की स्थिति माना जाता है। निम्नलिखित कोड पासफ़्रेज़ का उपयोग करके दिए गए संदेश को एन्क्रिप्ट करेगा:
import hashlib
import math
import os
from Crypto.Cipher import AES
IV_SIZE = 16 # 128 bit, fixed for the AES algorithm
KEY_SIZE = 32 # 256 bit meaning AES-256, can also be 128 or 192 bits
SALT_SIZE = 16 # This size is arbitrary
cleartext = b'Lorem ipsum'
password = b'highly secure encryption password'
salt = os.urandom(SALT_SIZE)
derived = hashlib.pbkdf2_hmac('sha256', password, salt, 100000,
dklen=IV_SIZE + KEY_SIZE)
iv = derived[0:IV_SIZE]
key = derived[IV_SIZE:]
encrypted = salt + AES.new(key, AES.MODE_CFB, iv).encrypt(cleartext)
एईएस एल्गोरिथ्म तीन पैरामीटर लेता है: एन्क्रिप्शन कुंजी, इनिशियलाइज़ेशन वेक्टर (IV) और एन्क्रिप्ट किया जाने वाला वास्तविक संदेश। यदि आपके पास बेतरतीब ढंग से उत्पन्न एईएस कुंजी है, तो आप उस एक का उपयोग कर सकते हैं और केवल एक यादृच्छिक आरंभीकरण वेक्टर उत्पन्न कर सकते हैं। एक पासफ़्रेज़ का आकार हालांकि सही नहीं है, और न ही इसे सीधे उपयोग करने के लिए अनुशंसित किया जाएगा, क्योंकि यह वास्तव में यादृच्छिक नहीं है और इस तरह तुलनात्मक रूप से थोड़ा एंट्रोपी है। इसके बजाय, हम पासवर्ड से 128 बिट आरंभीकरण वेक्टर और 256 बिट एन्क्रिप्शन कुंजी उत्पन्न करने के लिए PBKDF2 एल्गोरिथ्म के अंतर्निहित कार्यान्वयन का उपयोग करते हैं।
यादृच्छिक नमक पर ध्यान दें जो एन्क्रिप्ट किए गए प्रत्येक संदेश के लिए एक अलग आरंभीकरण वेक्टर और कुंजी होना महत्वपूर्ण है। यह विशेष रूप से सुनिश्चित करता है कि दो समान संदेश समान एन्क्रिप्टेड पाठ में परिणाम नहीं करेंगे, लेकिन यह हमलावरों को किसी अन्य पासफ़्रेज़ के साथ एन्क्रिप्ट किए गए संदेशों पर एक पासफ़्रेज़ का अनुमान लगाने के लिए खर्च किए गए काम को पुन: उपयोग करने से भी रोकता है। डिक्रिप्टिंग के लिए समान आरंभीकरण वेक्टर और कुंजी प्राप्त करने के लिए इस नमक को एन्क्रिप्टेड संदेश के साथ संग्रहीत किया जाना है।
निम्नलिखित कोड हमारे संदेश को फिर से डिक्रिप्ट करेगा:
salt = encrypted[0:SALT_SIZE]
derived = hashlib.pbkdf2_hmac('sha256', password, salt, 100000,
dklen=IV_SIZE + KEY_SIZE)
iv = derived[0:IV_SIZE]
key = derived[IV_SIZE:]
cleartext = AES.new(key, AES.MODE_CFB, iv).decrypt(encrypted[SALT_SIZE:])
Pycrypto का उपयोग करके RSA हस्ताक्षर बनाना
संदेश हस्ताक्षर बनाने के लिए RSA का उपयोग किया जा सकता है। एक वैध हस्ताक्षर केवल निजी आरएसए कुंजी तक पहुंच के साथ उत्पन्न किया जा सकता है, दूसरी तरफ वैधता केवल संबंधित सार्वजनिक कुंजी के साथ संभव है। इसलिए जब तक दूसरा पक्ष आपकी सार्वजनिक कुंजी जानता है, तब तक वे आपके द्वारा हस्ताक्षरित और अपरिवर्तित संदेश को सत्यापित कर सकते हैं - उदाहरण के लिए ईमेल के लिए उपयोग किया जाने वाला तरीका। वर्तमान में, इस कार्यक्षमता के लिए pycrypto जैसे तृतीय-पक्ष मॉड्यूल की आवश्यकता है।
import errno
from Crypto.Hash import SHA256
from Crypto.PublicKey import RSA
from Crypto.Signature import PKCS1_v1_5
message = b'This message is from me, I promise.'
try:
with open('privkey.pem', 'r') as f:
key = RSA.importKey(f.read())
except IOError as e:
if e.errno != errno.ENOENT:
raise
# No private key, generate a new one. This can take a few seconds.
key = RSA.generate(4096)
with open('privkey.pem', 'wb') as f:
f.write(key.exportKey('PEM'))
with open('pubkey.pem', 'wb') as f:
f.write(key.publickey().exportKey('PEM'))
hasher = SHA256.new(message)
signer = PKCS1_v1_5.new(key)
signature = signer.sign(hasher)
हस्ताक्षर का सत्यापन करना समान रूप से काम करता है लेकिन निजी कुंजी के बजाय सार्वजनिक कुंजी का उपयोग करता है:
with open('pubkey.pem', 'rb') as f:
key = RSA.importKey(f.read())
hasher = SHA256.new(message)
verifier = PKCS1_v1_5.new(key)
if verifier.verify(hasher, signature):
print('Nice, the signature is valid!')
else:
print('No, the message was signed with the wrong private key or modified')
नोट : उपरोक्त उदाहरण PKCS # 1 v1.5 हस्ताक्षर एल्गोरिथ्म का उपयोग करते हैं जो बहुत आम है। pycrypto नए PKCS # 1 PSS एल्गोरिथ्म को भी लागू करता है, PKCS1_v1_5
को PKCS1_PSS
के उदाहरणों में बदलकर काम करना चाहिए यदि आप उस एक का उपयोग करना चाहते हैं। वर्तमान में इसका उपयोग करने के लिए कम कारण प्रतीत होता है।
Pymrypto का उपयोग करके असममित आरएसए एन्क्रिप्शन
असममित एन्क्रिप्शन का यह लाभ है कि संदेश प्राप्त करने वाले के साथ गुप्त कुंजी का आदान-प्रदान किए बिना संदेश को एन्क्रिप्ट किया जा सकता है। प्रेषक को केवल प्राप्तकर्ता को सार्वजनिक कुंजी जानने की आवश्यकता है, यह संदेश को इस तरह से एन्क्रिप्ट करने की अनुमति देता है कि केवल निर्दिष्ट प्राप्तकर्ता (जिसके पास निजी कुंजी है) उसे डिक्रिप्ट कर सकता है। वर्तमान में, इस कार्यक्षमता के लिए pycrypto जैसे तृतीय-पक्ष मॉड्यूल की आवश्यकता है।
from Crypto.Cipher import PKCS1_OAEP
from Crypto.PublicKey import RSA
message = b'This is a very secret message.'
with open('pubkey.pem', 'rb') as f:
key = RSA.importKey(f.read())
cipher = PKCS1_OAEP.new(key)
encrypted = cipher.encrypt(message)
प्राप्तकर्ता संदेश को डिक्रिप्ट कर सकता है, यदि उनके पास सही निजी कुंजी है:
with open('privkey.pem', 'rb') as f:
key = RSA.importKey(f.read())
cipher = PKCS1_OAEP.new(key)
decrypted = cipher.decrypt(encrypted)
नोट : उपरोक्त उदाहरण PKCS # 1 OAEP एन्क्रिप्शन योजना का उपयोग करते हैं। pycrypto PKCS # 1 v1.5 एन्क्रिप्शन योजना को भी लागू करता है, यह एक नए प्रोटोकॉल के लिए अनुशंसित नहीं है, हालांकि ज्ञात कैविट्स के कारण।