LSB Steganography in Secure Chat Environment
بسم الله الرحمن الرحيم ،،
علم الإخفاء Covered Writting أو ما يعرف بSteganograhy يعتبر من الوسائل الفعالة في عملية اخفاء المعلومات ، حيث من خلال الخوارزميات يمكن أن نضع ما نريده من بيانات داخل وسيط أخر (TCP/IP Header ، أو حتى NTFS Alternate Stream في أنظمة الويندوز ، أو حتى في الوسائط المتعددة مثل الصورة ، صوت ، فيدو وغير ذلك..) بدون التأثير على جودة ذلك الوسيط ،، وبالتالي اذا كان هناك متطفل على النظام أو خلال عملية الإرسال فلن يستطيع كشف البيانات التي تم تخبئتها .
من الخوارزميات المبسطة في الStegangoraphy ، فكرتها تكمن في أخذ أي bit من البيانات التي نريد اخفائها على حدة ، وادخال هذا الbit في البت الأول lsb من كل بايت في الوسيط الذي نريد الإخفاء فيه ،، المثال التالي يبين الإخفاء داخل صورة من نوع PNG-24 bit والصور من هذا النوع يتكون البكسل فيها من 3 بايتات الأول يمثل RED والثاني يمثل GREEN والثالث يمثل BLUE . وسنقوم باخفاء البت التالي من البيانات في الlsb من البايت التالي وهكذا ..
الشكل يبين تركيب الصورة من نوع PNG 24-bit وكيف كل بكسل مكون من 3 بايت
الشكل يبين تركيب الرسالة التي سنخفيها في الصورة .
عملية الإخفاء ستتم بأخذ كل بت من الرسالة على حدة وأخفائه في البايت التالي من الصورة (بدئا من البايت x لأن البايتات من 1 الى x سيستخدم لحفظ طول الرسالة حتى يتم استخراجها فيما بعد) .
الشكل يبين عملية الإخفاء في الصورة
عملية استخراج الرسالة من الصورة تكون بأخذ كل بت من الlsb بدأ من البايت x وتجميعهم لكي يكونوا النص الأصلي ..
الشكل يبين عملة استخراج النص من الصورة
الناتج النهائي لن يختلف كثيرا عن الصورة الأصلية
يتم تطبيق تلك الخوارزمية برمجيا عن طريق قرائه الصورة من القرص باستخدام الكلاس ImageIO وسوف نحصل على الBufferedImage :
File imgPath = new File(ImageName);
BufferedImage bufferedImage = ImageIO.read(imgPath);
الBufferedImage يتكون من عدة كلاسين من الداخل كما بالشكل :
الكلاس Raster وهو المسؤول عن محتوى الصورة ، ويحتوي على كلاسين الأول DataBuffer وهو ويحمل على جميع البيانات ، والثاني SimpleModel هو الذي يفسر تلك البيانات على شكل بكسل ، الكلاس الثاني في الBufferedImage هو ColorModel وهو الذي يتعامل مع ألوان تلك البسكل ، ما نريده في هذه الخطوه هو الحصول على محتوى الصورة DataBuffer كما يلي :
WritableRaster raster = img.getRaster();
DataBufferByte data = (DataBufferByte) raster.getDataBuffer();
return ( data.getData() );
}
بعد الحصول على البايت نقوم بعملية الإخفاء باستخدام الدالة hide :
if ( text.length + offset > image.length )
throw new IOException();
for (int i=0; i< text.length ; i++) {
int add = text[i];
for (int bit=7 ; bit>=0 ; bit--,offset++) {
int b = (add >>> bit) & 1 ;
image[offset] = (byte) ( (image[offset] & 0xFE) | b );
}
}
return ( image );
}
عملية الإسترجاع تكون أولا بمعرفة طول النص ثم عمل حلقة بذلك الطول ،، لاحظ الحلقة الأولى 32 لأن الinteger وهو طول النص مكون من 32 بت .
int length = 0;
int offset = 32;
for(int i=0; i<32; ++i)
length = (length << 1) | (image[i] & 1);
byte[] result = new byte[length];
for(int b=0; b<result.length; ++b ) {
for(int i=0; i<8; ++i, ++offset)
result[b] = (byte)((result[b] << 1) | (image[offset] & 1));
}
return (result);
}
بذلك قد نكون انتهينا من الجزء الأول من الموضوع وهو شرح الlsb وتطبيقها بلغه الجافا ، ويمكن تطبيق ذلك في اي لغه برمجه ،،
الرد التالي ونكمل في الSecure Chatting ..
مراجع هذا الجزء :
JavaArt Chapter 6. Steganography
Steganography in java
Secure Chat in Java:
سنستعرض الأن النظام وهو عباره عن Chatting ولكنه يدعم خاصية ارسال الصور محمله بنصوص عادية أو حتى نصوص مشفره Cipher Text ،، والفكرة هي بدمج التشفير مع الStegangraphy سوف نحصل على أمنية أفضل بكل تأكيد على استخدام طريقة واحدة فقط ،، التشفير سوف يتم باستخدام خوارزمية الAES ، ولكن كما هو معروف فإن هذه الخوارزمية تحتاج الى مفتاح Symmetric Cipher للتشفير ، والمشكلة تبدأ في كيفية ارسال هذا المفتاح من الطرف الى الطرف الأخر ؟
حل هذه المشكلة عن طريق شفرة الRSA ، حيث يتم من خلالها تبادل المفاتيح ، سبق أن تنتاولنا هذا الموضوع في مكتبة الJCrypto (والتي تم استخدامها في هذا المثال أيضا ) .. الأن لدينا عدة حلول لتبادل هذه المفاتيح ،، الأول هو أن يقوم الطرف A والطرف B بتبادل المفاتيح من خلال السيرفر (وظيفة السيرفر هنا تمرير المفاتيح فقط) .. الحل الأخر جعل السيرفر يولد مفتاح التشفير session key بشكل عشوائي ، وأي client يتصل بهذا السيرفر يقوم السيرفر باعطائها هذا المفتاح الذي يستخدم في التشفير (السيرفر يمرر المفتاح للعميل عن طريق RSA بالطبع) وسوف نستخدم هذا الحل ..
بهذا الحل يكون السيرفر هو المسؤول عن انشاء المفاتيح وارسال هذه المفاتيح لأي كلاينت يريد الإتصال به .. أي يمكن القول بأنه
Trusted third party وهكذا الكلاينت لن يحتاج لتوليد مفاتيح تشفير أو ماشابه (فقط مفاتيح RSA لكي يحصل على AES key من السيرفر) .
هذه هي فكرة البرنامج ،، ويستخدم قاعده بيانات Derby لأنه عباره عن Chat مثل MSN Messagner وأي كلاينت قد يكون لديه في Contact List مجموعة من الclients الأخرين (وتتغير الحالة من offline الى online لأي كلاينت في الcontact list عندما يقوم بعمل singin ) ..
عند أول استخدام للنظام سوف يتم عمل قاعده البيانات في المسار C:\\SECURE_DB لكي يتم حفظ بيانات الClients والContact list الخاصه بهم ..
النظام يمكن تحميله من خلال هذا الرابط (بحجم 5 ميغا) .. ويحتوي على مجلدين :
الأول Executable ويحتوي على ملف CClient.jar يمثل العميل و الCServer.jar للسيرفر ، وlib بداخله يحتوى على المكتبات المستخدمة.
الثاني هو Source Code ويمكن فتح المشروعين مباشره من خلال الnetbeans .
Screenshots:
قم بفتح ملف الCServer.jar على جهاز السيرفر ،، وقم بالإتصال بعد عمل run ،، ستجد أنه سيأخذ بعضا من الوقت لإنشاء الDB ولتوليد مفاتيح التشفير AES Key (فقط مفتاح واحد عند كل مرة تشغيل للسيرفر) ..
هناك نافذه على الجهه اليمني باسم log تقوم بعرض كل العمليات التي يتم اجرائها على السيرفر في اللحظة ..
بعد ذلك يمكن لأي عدد من الكلاينت ان يتصل بالسيرفر وتسجيل حساب فيه ، قم بتشغيل الCClient.jar ، وبما أن هذه أول مرة قم بعمل حساب جديد وذلك من خلال الرابط Signup وكتابة اسم المستخدم وكلمة المرور .. بعد انشاء الحساب وظهور رسالة الإشعار بذلك ، ستجد أن النظام يسهل لك كتابة المعلومات مرة أخرى ويتم كتابتها تلقائيا فقط عليك بعمل تسجيل الدخول Signin . لاحظ أيضا قائمه options ستجد بها زر connection لتحديد رقم الIp والport للسيرفر ، الخيارات الإفتراضية هي للسيرفر على الجهاز المحلي والبورت الإفتراضي للسيرفر 5000 (الا اذا قمت بتغييره عند فتح السيرفر ستحتاج أن تغيره هنا أيضا) .
يمكنك النظر على الlog بالسيرفر وستجد أنه وضح ان هناك عملية تسجيل وبعد تسجيل دخولك يوضح أيضا بأن هناك عملية loggin أيضا ستجد أن كل النظام يقوم بعملية تبديل مفتاح التشفير فور دخول العميل للنظام ..
سنقوم الأن بعمل المحادثه بين العميلين ahmed وali بما أنهم online ،، قم بالضغط دبل كليك على اسم العميل ، وتقوم نافذه الشات بالظهور ،، عند فتحك هذه النافذه وكتابة رسالة سوف تذهب للطرف الأخر (من خلال السيرفر) وفي حال لم تكن هناك نافذه شات مفتوحة سوف تظهر لك نافذه بشكل تلقائي ..
الأن لكي يتم ارسال صورة وبداخلها نص مشفر يتم وضع علامة صح على كل من المربعين وتحديد الصورة التي تريد ارسالها وكتابة النص ثم الضغط على send بعدها سوف يجد الطرف الأخر رسالة (مربع dialog) بأن هناك صورة ولديه خيارين اما الموافقه او الرفض ، بعد الموافقه سيتم فتح نافذه جديده لعرض الصورة ، بها خيار اظهار النص ، أو اظهار النص الأصلي (اذا كان النص الموجود مشفر) وخيار حفظ النص clear text في ملف text .
هذا كل ما في الأمر .. ويمكن النظر للكود المصدر للفائده ،،
بالتوفيق،،
معلومات اكثر من رائعة اخي وجدي .
سلمت يداك