تجزئة آمنة باستخدام Python Hashlib

سيعلمك هذا البرنامج التعليمي كيفية إنشاء تجزئات آمنة باستخدام وظائف مدمجة من وحدة هاشليب في بايثون.
يمكن أن يكون فهم أهمية التجزئة وكيفية حساب التجزئة الآمنة برمجيًا مفيدًا – حتى إذا كنت لا تعمل في أمان التطبيق. لكن لماذا؟
حسنًا ، عند العمل في مشاريع Python ، من المحتمل أن تصادف حالات تشعر فيها بالقلق بشأن تخزين كلمات المرور وغيرها من المعلومات الحساسة في قواعد البيانات أو ملفات التعليمات البرمجية المصدر. في مثل هذه الحالات ، يكون من الأكثر أمانًا تشغيل خوارزمية التجزئة على المعلومات الحساسة وتخزين التجزئة بدلاً من المعلومات.
في هذا الدليل ، سنغطي ماهية التجزئة وكيف تختلف عن التشفير. سنستعرض أيضًا خصائص وظائف التجزئة الآمنة. بعد ذلك ، سنستخدم خوارزميات التجزئة الشائعة لحساب تجزئة النص العادي في بايثون. للقيام بذلك ، سنستخدم وحدة hashlib المدمجة.
لكل هذا وأكثر ، فلنبدأ!
ما هو التجزئة؟
تأخذ عملية التجزئة سلسلة رسالة وتعطي ناتجًا بطول ثابت يسمى التجزئة. بمعنى أن طول تجزئة الإخراج لخوارزمية تجزئة معينة ثابت – بغض النظر عن طول الإدخال. ولكن كيف يختلف عن التشفير؟
في التشفير ، يتم تشفير الرسالة أو النص العادي باستخدام خوارزمية تشفير تعطي مخرجات مشفرة. يمكننا بعد ذلك تشغيل خوارزمية فك التشفير على الإخراج المشفر لاستعادة سلسلة الرسالة.
ومع ذلك ، فإن التجزئة تعمل بشكل مختلف. لقد علمنا للتو أن عملية التشفير قابلة للعكس حيث يمكنك الانتقال من الرسالة المشفرة إلى الرسالة غير المشفرة والعكس صحيح.
على عكس التشفير ، فإن التجزئة ليست عملية قابلة للعكس ، مما يعني أنه لا يمكننا الانتقال من التجزئة إلى رسالة الإدخال.
خصائص وظائف التجزئة
دعنا ننتقل بسرعة إلى بعض الخصائص التي يجب أن تفي بها وظائف التجزئة:
- حتمية: وظائف التجزئة حتمية. بالنظر إلى الرسالة m ، فإن تجزئة m هي نفسها دائمًا.
- مقاومة Preimage: لقد غطينا هذا بالفعل عندما قلنا أن التجزئة ليست عملية قابلة للعكس. تنص خاصية المقاومة preimage على أنه من غير المجدي العثور على الرسالة m من تجزئة الإخراج.
- مقاومة الاصطدام: يجب أن يكون من الصعب (أو غير مجدي من الناحية الحسابية) العثور على سلسلتين مختلفتين للرسائل m1 و m2 بحيث يكون تجزئة m1 مساوية لتجزئة m2. هذه الخاصية تسمى مقاومة الاصطدام.
- الثانية Preimage Resistant: هذا يعني أنه بالنظر إلى الرسالة m1 والتجزئة المقابلة لها ، من غير الممكن العثور على رسالة أخرى m2 مثل التجزئة (m1) = التجزئة (m2).
وحدة هاشليب بيثون
توفر وحدة hashlib المدمجة في Python تطبيقات للعديد من خوارزميات التجزئة وهضم الرسائل بما في ذلك خوارزميات SHA و MD5.
لاستخدام المنشئات والوظائف المضمنة من وحدة Python hashlib ، يمكنك استيرادها إلى بيئة العمل الخاصة بك مثل:
import hashlib
توفر وحدة hashlib الثوابت algorithms_available و algorithms_guaranteed ، والتي تشير إلى مجموعة الخوارزميات التي تتوفر تطبيقاتها ومضمونة على النظام الأساسي ، على التوالي.
لذلك ، فإن algorithms_guaranteed هي مجموعة فرعية من algorithms_available.
ابدأ تشغيل Python REPL ، واستورد hashlib ، وقم بالوصول إلى ثوابت algorithms_available_guaranteed_guaranteed:
>>> hashlib.algorithms_available
# Output {'md5', 'md5-sha1', 'sha3_256', 'shake_128', 'sha384', 'sha512_256', 'sha512', 'md4', 'shake_256', 'whirlpool', 'sha1', 'sha3_512', 'sha3_384', 'sha256', 'ripemd160', 'mdc2', 'sha512_224', 'blake2s', 'blake2b', 'sha3_224', 'sm3', 'sha224'}
>>> hashlib.algorithms_guaranteed
# Output {'md5', 'shake_256', 'sha3_256', 'shake_128', 'blake2b', 'sha3_224', 'sha3_384', 'sha384', 'sha256', 'sha1', 'sha3_512', 'sha512', 'blake2s', 'sha224'}
نرى أن algorithms_guaranteed هي بالفعل مجموعة فرعية من الخوارزميات المتاحة
كيفية إنشاء كائنات تجزئة في بايثون
بعد ذلك ، دعنا نتعلم كيفية إنشاء كائنات التجزئة في بايثون. سنحسب تجزئة SHA256 لسلسلة رسالة باستخدام الطرق التالية:
- المُنشئ العام الجديد ()
- المنشئات الخاصة بالخوارزمية
استخدام () المُنشئ الجديد
دعنا نبدأ سلسلة الرسالة:
>>> message = "admingate.org is awesome!"
لإنشاء كائن التجزئة ، يمكننا استخدام المُنشئ الجديد () وتمرير اسم الخوارزمية كما هو موضح:
>>> sha256_hash = hashlib.new("SHA256")
يمكننا الآن استدعاء طريقة update () على كائن التجزئة باستخدام سلسلة الرسالة كمتغير:
>>> sha256_hash.update(message)
إذا قمت بذلك ، فسوف تواجه خطأ لأن خوارزميات التجزئة لا يمكنها العمل إلا مع سلاسل البايت.
Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: Unicode-objects must be encoded before hashing
للحصول على السلسلة المشفرة ، يمكنك استدعاء طريقة encode () في سلسلة الأسلوب ، ثم استخدامها في استدعاء طريقة update (). بعد القيام بذلك ، يمكنك استدعاء طريقة hexdigest () للحصول على تجزئة sha256 المطابقة لسلسلة الرسالة.
sha256_hash.update(message.encode()) sha256_hash.hexdigest() # Output:'b360c77de704ad8f02af963d7da9b3bb4e0da6b81fceb4c1b36723e9d6d9de3d'
بدلاً من ترميز سلسلة الرسالة باستخدام طريقة encode () ، يمكنك أيضًا تعريفها كسلسلة من البايتات عن طريق إضافة البادئة للسلسلة بـ b كما يلي:
message = b"admingate.org is awesome!" sha256_hash.update(message) sha256_hash.hexdigest() # Output: 'b360c77de704ad8f02af963d7da9b3bb4e0da6b81fceb4c1b36723e9d6d9de3d'
التجزئة التي تم الحصول عليها هي نفس التجزئة السابقة ، مما يؤكد الطبيعة الحتمية لوظائف التجزئة.
بالإضافة إلى ذلك ، يجب أن يؤدي تغيير بسيط في سلسلة الرسالة إلى تغيير التجزئة بشكل كبير (المعروف أيضًا باسم “تأثير الانهيار الجليدي”).
للتحقق من ذلك ، دعنا نغير “a” في “رائع” إلى “A” ، ونحسب التجزئة:
message = "admingate.org is Awesome!" h1 = hashlib.new("SHA256") h1.update(message.encode()) h1.hexdigest() # Output: '3c67f334cc598912dc66464f77acb71d88cfd6c8cba8e64a7b749d093c1a53ab'
نرى أن الهاش يتغير تمامًا.
استخدام المُنشئ الخاص بالخوارزمية
في المثال السابق ، استخدمنا المُنشئ العام new () ومررنا “SHA256” كاسم للخوارزمية لإنشاء كائن التجزئة.
بدلاً من القيام بذلك ، يمكننا أيضًا استخدام مُنشئ sha256 () كما هو موضح:
sha256_hash = hashlib.sha256() message= "admingate.org is awesome!" sha256_hash.update(message.encode()) sha256_hash.hexdigest() # Output: 'b360c77de704ad8f02af963d7da9b3bb4e0da6b81fceb4c1b36723e9d6d9de3d'
تجزئة الإخراج مطابقة للتجزئة التي حصلنا عليها سابقًا لسلسلة الرسالة “admingate.org رائع!”.
استكشاف سمات كائنات التجزئة
تحتوي كائنات التجزئة على بعض السمات المفيدة:
- تشير السمة Digest_size إلى حجم الملخص بالبايت. على سبيل المثال ، تقوم خوارزمية SHA256 بإرجاع تجزئة 256 بت ، أي ما يعادل 32 بايت
- تشير سمة block_size إلى حجم الكتلة المستخدم في خوارزمية التجزئة.
- سمة الاسم هي اسم الخوارزمية التي يمكننا استخدامها في المُنشئ () الجديد. يمكن أن يكون البحث عن قيمة هذه السمة مفيدًا عندما لا تحتوي كائنات التجزئة على أسماء وصفية.
يمكننا التحقق من هذه السمات لكائن sha256_hash الذي أنشأناه سابقًا:
>>> sha256_hash.digest_size 32 >>> sha256_hash.block_size 64 >>> sha256_hash.name 'sha256'
بعد ذلك ، دعنا نلقي نظرة على بعض التطبيقات المثيرة للاهتمام للتجزئة باستخدام وحدة هاشليب في بايثون.
أمثلة عملية على التجزئة
التحقق من سلامة البرامج والملفات
كمطورين ، نقوم بتنزيل حزم البرامج وتثبيتها طوال الوقت. هذا صحيح بغض النظر عما إذا كنت تعمل على توزيعة Linux أو على Windows أو Mac.
ومع ذلك ، قد لا تكون بعض مرايا حزم البرامج جديرة بالثقة. يمكنك العثور على التجزئة (أو المجموع الاختباري) بجوار رابط التنزيل. ويمكنك التحقق من سلامة البرنامج الذي تم تنزيله عن طريق حساب التجزئة ومقارنتها مع التجزئة الرسمية.
يمكن تطبيق ذلك على الملفات الموجودة على جهازك أيضًا. حتى أصغر تغيير في محتويات الملف سيؤدي إلى تغيير التجزئة بشكل كبير ، يمكنك التحقق مما إذا كان الملف قد تم تعديله عن طريق التحقق من التجزئة.
هذا مثال بسيط. قم بإنشاء ملف نصي “my_file.txt” في دليل العمل ، وإضافة بعض المحتوى إليه.
$ cat my_file.txt This is a sample text file. We are going to compute the SHA256 hash of this text file and also check if the file has been modified by recomputing the hash.
يمكنك بعد ذلك فتح الملف في وضع القراءة الثنائي (‘rb’) ، وقراءة محتويات الملف وحساب تجزئة SHA256 كما هو موضح:
>>> import hashlib >>> with open("my_file.txt","rb") as file: ... file_contents = file.read() ... sha256_hash = hashlib.sha256() ... sha256_hash.update(file_contents) ... original_hash = sha256_hash.hexdigest()
هنا ، المتغير original_hash هو تجزئة “my_file.txt” في حالته الحالية.
>>> original_hash # Output: '53bfd0551dc06c4515069d1f0dc715d002d451c8799add29f3e5b7328fda9f8f'
الآن قم بتعديل الملف “my_file.txt”. يمكنك إزالة المسافة البيضاء الزائدة قبل كلمة “الذهاب”. 🙂
احسب التجزئة مرة أخرى وقم بتخزينها في متغير computed_hash.
>>> import hashlib >>> with open("my_file.txt","rb") as file: ... file_contents = file.read() ... sha256_hash = hashlib.sha256() ... sha256_hash.update(file_contents) ... computed_hash = sha256_hash.hexdigest()
يمكنك بعد ذلك إضافة عبارة تأكيد بسيطة تؤكد ما إذا كانت computed_hash تساوي original_hash.
>>> assert computed_hash == original_hash
إذا تم تعديل الملف (وهذا صحيح في هذه الحالة) ، يجب أن تحصل على خطأ Assertion:
Traceback (most recent call last): File "<stdin>", line 1, in <module> AssertionError
يمكنك استخدام التجزئة عند تخزين المعلومات الحساسة ، مثل كلمات المرور في قواعد البيانات. يمكنك أيضًا استخدام التجزئة في مصادقة كلمة المرور عند الاتصال بقواعد البيانات. تحقق من صحة تجزئة كلمة المرور المدخلة مقابل تجزئة كلمة المرور الصحيحة.
خاتمة
آمل أن يساعدك هذا البرنامج التعليمي في التعرف على كيفية إنشاء تجزئات آمنة باستخدام Python. فيما يلي النقاط الرئيسية:
- توفر وحدة هاشليب في بايثون تطبيقات جاهزة للاستخدام للعديد من خوارزميات التجزئة. يمكنك الحصول على قائمة الخوارزميات المضمونة على النظام الأساسي الخاص بك باستخدام hashlib.algorithms_guaranteed.
- لإنشاء كائن تجزئة ، يمكنك استخدام المُنشئ العام الجديد () مع بناء الجملة: hashlib.new (“algo-name”). بدلاً من ذلك ، يمكنك استخدام المُنشئين المتوافقين مع خوارزميات التجزئة المحددة ، مثل: hashlib.sha256 () لتجزئة SHA 256.
- بعد تهيئة سلسلة الرسالة المراد تجزئتها وكائن التجزئة ، يمكنك استدعاء طريقة update () في كائن التجزئة ، متبوعةً بالطريقة hexdigest () للحصول على التجزئة.
- يمكن أن يكون التجزئة مفيدًا عند التحقق من سلامة عناصر البرامج والملفات ، وتخزين المعلومات الحساسة في قواعد البيانات ، والمزيد.
بعد ذلك ، تعرف على كيفية ترميز مولد كلمة مرور عشوائي في Python.