• 0
Speed_Of_Light

التشفير باستخدام توابع Hash في كل اللغات!

سؤال

(أعتذر وضع الدرس هنا ... أعلم أنه ليس المكان الأنسب، لكن لم أجد مكاناً مناسباً له ... أتمنى من المشرفين نقل الدرس إلى المكان الأنسب)

ما هو التشفير باستخدام توابع Hashing؟

هي عملية توليد رقم أو مفتاح ثابت الطول من مجموعة من البيانات، أياً كان حجمها.

ربما كنت تتسائل الآن لماذا لم أقم بترجمة هذا المصطلح وأبقيته على ما هو عليه في مدونة تدّعي الاعتزاز بالعربية؟! الترجمة الحرفية لـ Hashing هي : الفرم أو المزج … وهذا لا يوصل المعنى بشكل كافٍ. إن كان لديك ترجمة أفضل الرجاء أخبرني.

إذاً تقوم خوارزمية الهاشينغ بإعادة قيمة من البيانات الممررة … ويتم هذه القيمة تسمى مفتاح أو رقم (بالانجليزية تسمى hash values, hash codes, hash sums, checksums أو hashes)

من أهم مزايا هذا المفتاح:

طوله ثابت: وذلك من أجل خوارزمية معينة مهما كان حجم البيانات.

متفرّد unique: أي لا يمكن أن ينتج نفس المفتاحين من أجل كتلتين مختلفتين من البيانات *

غير قابل للعكس: لا يمكنك انطلاقاً من المفتاح الوصول إلى البيانات أبداً، لكن يمكنك معرفة إذا ما كانت البيانات الأصلية متماثلة أم لا بمقارنة المفتاحين.

* (نظرياً هو غير متفرد، لكن عملياً عندما يكون احتمال تكرار نفس المفتاح قليل جداً جداً جداً ... يمكننها إهمال هذا الاحتمال بكل راحة)

استخدامات توابع التشفير باستخدام توابع Hashing:

أهمية هذه التوابع كبيرة جداً ولها استخدامات عديدة ومتنوعة بالنسبة للمطورين، وهي قائمة على أساس المزايا والخواص السابقة التي يتمتع بها المفتاح … منها:

تشفير كلمات السر: وذلك قبل تخزينها في قاعدة البيانات، وعندما يدخل المستخدم كلمة السر يتم توليد المفتاح من الكلمة المدخلة مرة ثانية ومقارنتها مع الكلمة المخزنة في قاعدة البيانات، وبالتالي تبقى القاعدة آمنة حتى لو تمكن شخص غير مخوّل من الدخول إليها وقراءة كلمات السر.

التأكد من صحة نقل البيانات: وذلك بتوليد مفتاح من البيانات قبل نقلها، ثم توليده مرة ثانية بعد نقلها ثم مقارنة المفتاحين.

منع التكرار بتوليد مفاتيح متفرّدة: في موقع رفع ملفات مثلاً: يكن أن يتم توليد مفتاح خاص بكل ملف، وإذا قام مستخدم ما برفع ملف له نفس مفتاح ملف موجود مسبقاً، فهذا يعني أن الملف مكرر ولا داعي لتخزينه مرة أخرى وحجز مساحة خاصة له!

الخوارزميات الشهيرة:

هناك العديد من الخوارزميات هاشينغ الشهيرة والتي تتفاوت فيما بينها بالعديد من الأمور أهمها: طول المفتاح المولد وسرعة أدائها. أهم هذه الخوارزميات بالنسبة للمطور:

اسم الخوارزمية : طول المفتاح المولد

MD5 : 128bit

SHA-1 : 128bit

SHA-256 : 256bit

SHA-512 : 512bit

وهي مرتبة حسب السرعة (تنازلياً) وحسب القوة (تصاعدياً).

أمثلة بكل اللغات !

قبل البدء بالأمثلة، يجب التنويه إلى الملاحظات التالية:

- التوابع التالية بمختلف اللغات تقوم بحساب المفتاح لسلسة نصية، وبالتالي يصلح استخدامها في تشفير كلمات السر، ومع تعديلات بسيطة يمكن حساب المفاتيح من أجل الملفات أو غيرها من أنواع البيانات

- المفتاح الناتج عادة ما يكون على شكل بايتات، ولكن من المتعارف عليه أن يتم عرضها بترميز ست عشري … وهذه التوابع تقوم بذلك

- الأمثلة بالطبع لا تغطي كل لغات البرمجة ! لكنها تغطي أهمها.

كود جافا Java:

تابع تشفير باستخدام Hash لأهم الخوارزميات، مع صف اختبار:

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Formatter;
public class HashingInJava {
public static void main(String[] args) {
System.out.println(calcHash("سرعة الضوء", "MD5"));
System.out.println(calcHash("سرعة الضوء", "SHA-1"));
System.out.println(calcHash("سرعة الضوء", "SHA-256"));
System.out.println(calcHash("سرعة الضوء", "SHA-512"));
}
static String calcHash(String content, String algorithm) {
try {
byte hash[] = MessageDigest.getInstance(algorithm).digest(content.getBytes());
Formatter formatter = new Formatter();
for (byte b : hash) formatter.format("%02x", b);
return formatter.toString();
} catch (NoSuchAlgorithmException ex) {
}
return null;
}
}

كود سي شارب C#:

تابع تشفير باستخدام Hash لأهم الخوازرميات

public static string Encrypt(string data, string algorithm)
{
byte[] result = null;
switch (algorithm.ToLower())
{
case "md5":
result = new MD5CryptoServiceProvider().ComputeHash(Encoding.UTF8.GetBytes(data));
break;
case "sha1":
result = new SHA1CryptoServiceProvider().ComputeHash(Encoding.UTF8.GetBytes(data));
break;
case "sha256":
result = new SHA256CryptoServiceProvider().ComputeHash(Encoding.UTF8.GetBytes(data));
break;
case "sha512":
result = new SHA512CryptoServiceProvider().ComputeHash(Encoding.UTF8.GetBytes(data));
break;
}
string hex = "";
foreach (byte x in result)
{
hex += String.Format("{0:x2}", x);
}
return hex;
}

كود فيجوال بيزك دوت نيت VB.NET:

تابع تشفير باستخدام Hash لأهم الخوازرميات … نفس التابع السابق، لكن بلغة Visual Basic

Function Encrypt(ByVal data As String, ByVal algorithm As String) As String
Dim result() As Byte = System.Text.Encoding.Unicode.GetBytes(data)
Select Case algorithm.ToLower()
Case "md5"
result = New Security.Cryptography.MD5CryptoServiceProvider().ComputeHash(result)
Case "sha1"
result = New Security.Cryptography.SHA1CryptoServiceProvider().ComputeHash(result)
Case "sha256"
result = New Security.Cryptography.SHA256CryptoServiceProvider().ComputeHash(result)
Case "sha512"
result = New Security.Cryptography.SHA512CryptoServiceProvider().ComputeHash(result)
End Select
Dim hex As String = ""
For Each b As Byte In result
hex += b.ToString("x2")
Next
Return hex
End Function

كود بي إتش بي PHP:

الأمر أسهل بكثير مع php ، فالتابع موجود بشكل جاهز … كل ما عليك هو استخدامه !

<?php
echo hash('md5', 'سرعة الضوء');
echo hash('sha1', 'سرعة الضوء');
echo hash('sha256', 'سرعة الضوء');
echo hash('sha512', 'سرعة الضوء');
?>

كود C++ مع Qt:

مع Qt تابع توليد المفتاح موجود لكنه لا يدعم سوى Md4 و Md5 و Sha1

QCryptographicHash::hash("سرعة الضوء".toUtf8(), QCryptographicHash::Sha1).toHex();

قراءة التدوينة الأصلية

تم تعديل بواسطه Speed_Of_Light
6

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

9 إجابة على هذا السؤال .

  • 0

جزاك مولانا عنا خيرا ..

فعلا الدرس قوي و خصوصا أنه مميز في حماية البيانات المهمة بداخل قاعدة البيانات التي تتطلب نسبيا نوعا من الحماية القصوى.

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

إنتا مظبطنا أخي سرعة الضوء ... حاطط المثال ولا ب 5 لغات!

أستاذ ... ربما يكون لي عوده وأتسفيد من الدرس ... إن شاء الله

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

أهلاً بك أخ هويدي

إنتا مظبطنا أخي سرعة الضوء ... حاطط المثال ولا ب 5 لغات!

عذراً ... لم أفهم شيء

ممكن توضيح بالفصحى ؟

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

إنه مجرد مدح لموضوعك ... :D

أقول لك أنت مظبط موضوعك .... لدرجة أنك وضعت الكود في أكثر من خمس لغات برمجيه ...

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

بعد قراءة المقاله الرائعه لي ملاحظه صغيره...

بالنسبة لكود الجافا.. و خصوصا هذا السطر :

byte hash[] = MessageDigest.getInstance(algorithm).digest(content.getBytes());

لأن ال content يحتوي على أحرف UTF-8 ... أليس من الأفضل إستخدام

getBytes("UTF-8")

حيث أن getBytes() تستخدم ال default charset والتي ربما لم تكن UTF-8 ؟

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

توليد المفتاح يتم على مصفوفة البايتات ... أياً كانت محتوياتها

المشكلة التي يمكن أن تحدث هي أن يكون في السلسلة النصية حرف ليس من أحرف هذا الترميز.

ولا أظنها مشكلة بأي حال: فنحن لسنا مهتمين بعرض السلسة النصية ... بل نريدها بشكل مصفوفة من البايتات.

بالتالي سينتج معك في كلا الحالتين مفتاح فريد وصحيح ...

سؤال جانبي:

ماذا تقصد بالـ default charset ؟ هل هي خاصة بالنظام أم بمنصة جافا فقط ؟ وكيف يمكن تغييرها ؟

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

شوف:


byte hash[] = MessageDigest.getInstance(algorithm).digest(content.getBytes("ISO-8859-1"));
//a9c70fb337bc46412cae894b4f805e8702e8e067

byte hash[] = MessageDigest.getInstance(algorithm).digest(content.getBytes("UTF-8"));
//80639e32f28ccc398f1f7b34b32eb4e0c8c15386

إننا مهتمين بإعطاء النص للمستخدم و طلب ال hash منه..

مثلا لو فرضنا أن ال default encoding هو Latine-1 (ISO-88659-1)... و قمت أنت بعمل التالي:

String s = "مرحبا";

byte[] s_bytes = s.getBytes(); //

فإن ال s_bytes سيكون معتل ... لأنه إفترض أن النص عباره عن احرف من Latine-1 encoding ... وبالتالي فإن ال Hash لن تكون سليمه.. و أنت لا تعرف ما هو ال encoding الذي سوف يستخدمه!

لذا من الأفضل إستخدام UTF-8 في نظامك و تطلب أيضا من المستخدم صراحة أن يستخدم UTF-8..

بالنسبة للحصول على default encoding:

System.getProperty("file.encoding")

لعمل set لها ....

ممكن تستخدم -D

java -Dfile.encoding=ISO-8859-1 Hashing

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

لعمل set لها ....

ممكن تستخدم -D

java -Dfile.encoding=ISO-8859-1 Hashing

او استخدام



System.setProperty("file.encoding","UTF-8");

واظنها يجب ان تكون اول خطوة فى التطبيق

تحياتى

تم تعديل بواسطه MOHAMED FATHEI
0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

شكراً للمعلومات

نعم، بالطبع سينتج مفتاحين مختلفين، لكن لن يكون هناك فرق بالنسبة لنا طالما أن توليد المفتاح ومقارنته تتم على نفس الـ JVM (سواء كان تطبيق سطح مكتب أو تطبيق ويب ..)

وإلا ... فيجب اعتماد Encoding موحد كما تفضلت

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

من فضلك سجل دخول لتتمكن من التعليق

ستتمكن من اضافه تعليقات بعد التسجيل



سجل دخولك الان

  • يستعرض القسم حالياً   0 members

    لا يوجد أعضاء مسجلين يشاهدون هذه الصفحة .