ما هي أفضل طريقة لمنع الأشخاص من اختراق جدول أعلى الدرجات المستند إلى PHP في لعبة Flash

StackOverflow https://stackoverflow.com/questions/73947

سؤال

أنا أتحدث عن لعبة حركة ليس لها حد أعلى للدرجات ولا توجد طريقة للتحقق من النتيجة على الخادم من خلال إعادة تشغيل الحركات وما إلى ذلك.

ما أحتاجه حقًا هو أقوى تشفير ممكن في Flash/PHP، وطريقة لمنع الأشخاص من الاتصال بصفحة PHP بخلاف ملف Flash الخاص بي.لقد جربت بعض الأساليب البسيطة في الماضي لإجراء مكالمات متعددة للحصول على درجة واحدة وإكمال المجموع الاختباري / تسلسل فيبوناتشي وما إلى ذلك، وكذلك تشويش ملف SWF باستخدام Amayeta SWF Encrypt، ولكن تم اختراقها جميعًا في النهاية.

بفضل استجابات StackOverflow، وجدت الآن المزيد من المعلومات من Adobe - http://www.adobe.com/devnet/flashplayer/articles/secure_swf_apps_12.html و https://github.com/mikechambers/as3corelib - والذي أعتقد أنه يمكنني استخدامه للتشفير.لست متأكدًا من أن هذا سيجعلني أتغلب على CheatEngine بالرغم من ذلك.

أحتاج إلى معرفة أفضل الحلول لكل من AS2 وAS3، إذا كانت مختلفة.

يبدو أن المشاكل الرئيسية تتمثل في أشياء مثل رؤوس TamperData وLiveHTTP، لكنني أفهم أن هناك أدوات اختراق أكثر تقدمًا أيضًا - مثل CheatEngine (شكرًا مارك ويبستر)

هل كانت مفيدة؟

المحلول

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

  • من الأسهل إجراء هندسة عكسية لـ Flash مما قد تعتقد، نظرًا لأن الرموز الثانوية موثقة جيدًا وتصف لغة عالية المستوى (Actionscript) --- عندما تنشر لعبة Flash، فإنك تنشر كود المصدر الخاص بك، سواء كنت تعرف عليه أم لا.

  • يتحكم المهاجمون في ذاكرة وقت تشغيل مترجم Flash، بحيث يمكن لأي شخص يعرف كيفية استخدام مصحح أخطاء قابل للبرمجة تغيير أي متغير (بما في ذلك النتيجة الحالية) في أي وقت، أو تغيير البرنامج نفسه.

إن أبسط هجوم ممكن ضد نظامك هو تشغيل حركة مرور HTTP للعبة من خلال وكيل، والتقاط الحفظ عالي الدرجات، وإعادة تشغيله بنتيجة أعلى.

يمكنك محاولة منع هذا الهجوم عن طريق ربط كل نتيجة عالية يتم حفظها بمثيل واحد من اللعبة، على سبيل المثال عن طريق إرسال رمز مميز مشفر إلى العميل عند بدء تشغيل اللعبة، والذي قد يبدو كما يلي:

hex-encoding( AES(secret-key-stored-only-on-server, timestamp, user-id, random-number))

(يمكنك أيضًا استخدام ملف تعريف ارتباط الجلسة لنفس التأثير).

يقوم رمز اللعبة بتكرار هذا الرمز المميز مرة أخرى إلى الخادم مع حفظ النتيجة العالية.لكن لا يزال بإمكان المهاجم تشغيل اللعبة مرة أخرى، والحصول على رمز مميز، ثم لصق هذا الرمز المميز على الفور في عملية حفظ عالية النتيجة تم إعادة تشغيلها.

لذا، بعد ذلك، لن تقوم فقط بتغذية الرمز المميز أو ملف تعريف الارتباط للجلسة، ولكن أيضًا بمفتاح جلسة مشفر بدرجة عالية.سيكون هذا مفتاح AES 128 بت، وهو مشفر بحد ذاته باستخدام مفتاح مشفر في لعبة Flash:

hex-encoding( AES(key-hardcoded-in-flash-game, random-128-bit-key))

الآن قبل أن تنشر اللعبة النتيجة العالية، تقوم بفك تشفير مفتاح جلسة التشفير عالي الدرجات، وهو ما يمكنها القيام به لأنك قمت بترميز مفتاح فك تشفير مفتاح الجلسة عالي الدرجات في ملف Flash الثنائي.يمكنك تشفير النتيجة العالية باستخدام هذا المفتاح الذي تم فك تشفيره، بالإضافة إلى تجزئة SHA1 للنتيجة العالية:

hex-encoding( AES(random-128-bit-key-from-above, high-score, SHA1(high-score)))

يتحقق رمز PHP الموجود على الخادم من الرمز المميز للتأكد من أن الطلب جاء من مثيل لعبة صالح، ثم يقوم بفك تشفير النتيجة العالية المشفرة، والتحقق للتأكد من أن النتيجة العالية تطابق SHA1 للنتيجة العالية (إذا تخطيت هذه الخطوة ، سيؤدي فك التشفير ببساطة إلى الحصول على درجات عالية عشوائية، ومن المحتمل أن تكون عالية جدًا).

والآن، يقوم المهاجم بفك تشفير كود Flash الخاص بك ويعثر بسرعة على كود AES، الذي يبرز كإبهام مؤلم، على الرغم من أنه حتى لو لم يحدث ذلك، فسيتم تعقبه خلال 15 دقيقة من خلال البحث في الذاكرة والتتبع ("أعرف ذلك"). نتيجتي في هذه اللعبة هي 666، لذلك دعونا نجد 666 في الذاكرة، ثم نلتقط أي عملية تمس هذه القيمة --- أوه، انظر، رمز التشفير عالي الدرجات!").باستخدام مفتاح الجلسة، لا يحتاج المهاجم حتى إلى تشغيل رمز Flash؛إنها تحصل على رمز إطلاق اللعبة ومفتاح الجلسة ويمكنها إرسال درجة عالية عشوائية.

أنت الآن في النقطة التي يتخلى فيها معظم المطورين عن --- إعطاء أو أخذ بضعة أشهر من العبث مع المهاجمين من خلال:

  • تشفير مفاتيح AES باستخدام عمليات XOR

  • استبدال صفائف بايت المفتاح بالوظائف التي تحسب المفتاح

  • تشتيت تشفيرات المفاتيح المزيفة ومنشورات ذات درجات عالية في جميع أنحاء الملف الثنائي.

وهذا كله في الغالب مضيعة للوقت.وغني عن القول أن طبقة المقابس الآمنة (SSL) لن تساعدك أيضًا؛لا تستطيع طبقة المقابس الآمنة (SSL) حمايتك عندما تكون إحدى نقطتي نهاية طبقة المقابس الآمنة (SSL) شريرة.

فيما يلي بعض الأشياء التي يمكن أن تقلل فعليًا من الاحتيال عالي الدرجات:

  • اطلب تسجيل الدخول لتشغيل اللعبة، واطلب من تسجيل الدخول إنشاء ملف تعريف ارتباط للجلسة، ولا تسمح بتشغيل عدة ألعاب معلقة في نفس الجلسة، أو جلسات متزامنة متعددة لنفس المستخدم.

  • رفض النتائج العالية من جلسات اللعبة التي تدوم أقل من أقصر الألعاب الحقيقية التي تم لعبها على الإطلاق (للحصول على نهج أكثر تطورًا، حاول "عزل" النتائج العالية لجلسات اللعبة التي تدوم أقل من انحرافين معياريين أقل من متوسط ​​مدة اللعبة).تأكد من تتبع فترات اللعبة على جانب الخادم.

  • رفض النتائج العالية أو عزلها من عمليات تسجيل الدخول التي لعبت اللعبة مرة أو مرتين فقط، بحيث يتعين على المهاجمين إنتاج "سجل ورقي" من اللعب ذو المظهر المعقول لكل تسجيل دخول يقومون بإنشائه.

  • تسجل "نبضات القلب" أثناء اللعب، بحيث يرى الخادم الخاص بك نمو النقاط على مدار فترة اللعب الواحدة.ارفض النتائج العالية التي لا تتبع منحنيات درجات معقولة (على سبيل المثال، القفز من 0 إلى 999999).

  • حالة اللعبة "لقطة" أثناء اللعب (على سبيل المثال، كمية الذخيرة، والموقع في المستوى، وما إلى ذلك)، والتي يمكنك التوفيق بينها لاحقًا مقابل النتائج المؤقتة المسجلة.ولا يتعين عليك حتى أن يكون لديك طريقة للكشف عن الحالات الشاذة في هذه البيانات للبدء بها؛كل ما عليك فعله هو جمعها، ومن ثم يمكنك العودة وتحليلها إذا كانت الأمور تبدو مريبة.

  • قم بتعطيل حساب أي مستخدم يفشل في أحد فحوصات الأمان الخاصة بك (على سبيل المثال، عن طريق إرسال درجة عالية مشفرة تفشل في التحقق من الصحة).

تذكر أنك تقوم فقط بمنع عمليات الاحتيال ذات الدرجات العالية هنا.هناك لا شئ يمكنك القيام به لمنع إذا.إذا كان هناك أموال على المحك في لعبتك، فسيهزم شخص ما أي نظام تتوصل إليه.الهدف ليس ل قف هذا الهجوم؛إنه جعل الهجوم أكثر تكلفة من مجرد التفوق في اللعبة والتغلب عليها.

نصائح أخرى

ربما تسأل السؤال الخطأ.يبدو أنك تركز على الأساليب التي يستخدمها الأشخاص للوصول إلى أعلى قائمة النتائج، ولكن حظر أساليب معينة لا يؤدي إلا إلى أبعد من ذلك.ليست لدي أي خبرة في استخدام TamperData، لذا لا يمكنني التحدث عن ذلك.

السؤال الذي يجب أن تطرحه هو:"كيف يمكنني التحقق من أن الدرجات المقدمة صالحة وحقيقية؟" الطريقة المحددة للقيام بذلك تعتمد على اللعبة.بالنسبة لألعاب الألغاز البسيطة جدًا، يمكنك إرسال النتيجة مع حالة البداية المحددة وتسلسل الحركات التي أدت إلى الحالة النهائية، ثم إعادة تشغيل اللعبة على جانب الخادم باستخدام نفس الحركات.تأكد من أن النتيجة المذكورة هي نفس النتيجة المحسوبة ولا تقبل النتيجة إلا إذا كانت متطابقة.

تتمثل إحدى الطرق السهلة للقيام بذلك في توفير تجزئة تشفير لقيمة أعلى الدرجات الخاصة بك بالإضافة إلى النتيجة نفسها.على سبيل المثال، عند نشر النتائج عبر HTTP GET:http://example.com/highscores.php?score=500&checksum=0a16df3dc0301a36a34f9065c3ff8095

عند حساب هذا المجموع الاختباري، يجب استخدام سر مشترك؛لا ينبغي أبدًا نقل هذا السر عبر الشبكة، ولكن يجب أن يتم ترميزه بشكل ثابت داخل كل من الواجهة الخلفية لـ PHP والواجهة الأمامية للفلاش.تم إنشاء المجموع الاختباري أعلاه عن طريق إضافة السلسلة "سر"إلى النتيجة"500"، وتشغيله من خلال md5sum.

على الرغم من أن هذا النظام سيمنع المستخدم من نشر نتائج عشوائية، إلا أنه لا يمنع "هجوم إعادة التشغيل"، حيث يقوم المستخدم بإعادة نشر النتيجة المحسوبة مسبقًا ومجموعة التجزئة.في المثال أعلاه، النتيجة 500 ستنتج دائمًا نفس سلسلة التجزئة.يمكن التخفيف من بعض هذه المخاطر من خلال دمج المزيد من المعلومات (مثل اسم المستخدم أو الطابع الزمني أو عنوان IP) في السلسلة التي سيتم تجزئتها.وعلى الرغم من أن هذا لن يمنع إعادة تشغيل البيانات، إلا أنه سيضمن أن مجموعة البيانات صالحة فقط لمستخدم واحد في المرة الواحدة.

كى تمنع أي من حدوث هجمات إعادة التشغيل، يجب إنشاء نوع من نظام الاستجابة للتحدي، مثل ما يلي:

  1. تقوم لعبة الفلاش ("العميل") بإجراء HTTP GET لـ http://example.com/highscores.php مع عدم وجود المعلمات.ترجع هذه الصفحة قيمتين:بشكل عشوائي ملح القيمة، وتجزئة التشفير لتلك القيمة الملحة مع السر المشترك.يجب تخزين قيمة الملح هذه في قاعدة بيانات محلية للاستعلامات المعلقة، ويجب أن يكون لها طابع زمني مرتبط بها بحيث يمكن أن "تنتهي صلاحيتها" بعد دقيقة واحدة.
  2. تجمع لعبة الفلاش بين قيمة الملح والسر المشترك وتحسب التجزئة للتحقق من تطابقها مع القيمة المقدمة من الخادم.هذه الخطوة ضرورية لمنع التلاعب بقيم الملح من قبل المستخدمين، حيث أنها تتحقق من أن قيمة الملح تم إنشاؤها بالفعل بواسطة الخادم.
  3. تجمع لعبة الفلاش بين قيمة الملح والسر المشترك وقيمة النقاط العالية وأي معلومات أخرى ذات صلة (الاسم المستعار وعنوان IP والطابع الزمني)، وتحسب التجزئة.ثم يرسل هذه المعلومات مرة أخرى إلى الواجهة الخلفية لـ PHP عبر HTTP GET أو POST، بالإضافة إلى قيمة الملح والنتيجة العالية والمعلومات الأخرى.
  4. يجمع الخادم المعلومات المستلمة بنفس الطريقة التي يتم تلقيها من العميل، ويحسب التجزئة للتحقق من تطابقها مع تلك المقدمة من العميل.ثم يتحقق أيضًا من أن قيمة الملح لا تزال صالحة كما هي مدرجة في قائمة الاستعلامات المعلقة.إذا تحققت هذين الشرطين، فإنه يكتب الدرجة العالية إلى جدول النقاط العالية ويعيد رسالة "نجاح" موقعة إلى العميل.كما أنه يزيل قيمة الملح من قائمة الاستعلامات المعلقة.

يرجى أن تضع في اعتبارك أن أمان أي من الأساليب المذكورة أعلاه يتعرض للخطر إذا كان السر المشترك متاحًا للمستخدم

وكبديل، يمكن تجنب بعض هذه المراسلات عن طريق إجبار العميل على الاتصال بالخادم عبر HTTPS، والتأكد من تكوين العميل مسبقًا بحيث يثق فقط في الشهادات الموقعة من قبل مرجع مصدق محدد والذي يمكنك وحدك الوصول إليه .

يعجبني ما قاله tpqf، ولكن بدلاً من تعطيل الحساب عند اكتشاف الغش، قم بتنفيذ مصيدة جذب، لذلك كلما قاموا بتسجيل الدخول، فإنهم يرون نتائجهم المخترقة ولا يشكون أبدًا في أنه تم تصنيفهم على أنهم متصيدون.ابحث عن "phpBB MOD Troll" في Google وسترى طريقة بارعة.

في الإجابة المقبولة، يذكر tqbf أنه يمكنك فقط إجراء بحث في الذاكرة عن متغير النتيجة ("درجتي هي 666 لذا أبحث عن الرقم 666 في الذاكرة").

هناك طريقة للتغلب على هذا.لدي فصل دراسي هنا: http://divillysausages.com/blog/safenumber_and_safeint

في الأساس، لديك شيء لتخزين درجاتك.في أداة الضبط، يقوم بضرب القيمة التي تمررها برقم عشوائي (+ و-)، وفي أداة الضبط تقوم بتقسيم القيمة المحفوظة على المضاعف العشوائي لاستعادة القيمة الأصلية.إنه أمر بسيط، ولكنه يساعد في إيقاف البحث في الذاكرة.

شاهد أيضًا مقطع الفيديو الخاص ببعض الأشخاص الذين يقفون وراء محرك PushButton والذين يتحدثون عن بعض الطرق المختلفة التي يمكنك من خلالها مكافحة القرصنة: http://zaa.tv/2010/12/the-art-of-hacking-flash-games/.لقد كانوا مصدر الإلهام وراء الفصل.

لقد قمت بنوع من الحل ...لقد حصلت على عرض حيث زادت الدرجات (تحصل دائمًا على درجة +1).أولاً، بدأت العد من رقم عشوائي (على سبيل المثال 14 ) وعندما أعرض النتائج، أظهرت النتائج var ناقص 14.كان هذا يعني أنه إذا بحث المفرقعات عن 20 مثلاً، فلن يجدوه (سيكون 34 في الذاكرة).ثانياً، بما أنني أعرف ما هي النقطة التالية التي يجب أن تكون...لقد استخدمت مكتبة adobe crypto لإنشاء تجزئة النقطة التالية يجب ان يكون.عندما يتعين علي زيادة الدرجات، أتحقق مما إذا كان تجزئة الدرجات المتزايدة مساوية للتجزئة.إذا قام المفرقع بتغيير النقاط في الذاكرة، فإن التجزئة ليست متساوية.قمت بإجراء بعض عمليات التحقق من جانب الخادم وعندما حصلت على نقاط مختلفة من اللعبة ومن PHP، أعلم أن هناك غشًا.إليك مقتطف من الكود الخاص بي (أنا أستخدم فئة Adobe Crypto libraty MD5 وملح التشفير العشوائي.callPhp() هو التحقق من جانب الخادم الخاص بي)

private function addPoint(event:Event = null):void{
            trace("expectedHash: " + expectedHash + "  || new hash: " + MD5.hash( Number(SCORES + POINT).toString() + expectedHashSalt) );
            if(expectedHash == MD5.hash( Number(SCORES + POINT).toString() + expectedHashSalt)){
                SCORES +=POINT;
                callPhp();
                expectedHash = MD5.hash( Number(SCORES + POINT).toString() + expectedHashSalt);
            } else {
                //trace("cheat engine usage");
            }
        }

باستخدام هذه التقنية + تشويش SWF، تمكنت من إيقاف المفرقعات.أيضًا، عندما أقوم بإرسال النتائج إلى جانب الخادم، أستخدم وظيفة التشفير/فك التشفير الصغيرة الخاصة بي.شيء من هذا القبيل (لم يتم تضمين الكود الجانبي للخادم، ولكن يمكنك رؤية الخوارزمية وكتابتها بلغة PHP):

package  {

    import bassta.utils.Hash;

    public class ScoresEncoder {

        private static var ranChars:Array;
        private static var charsTable:Hash;

        public function ScoresEncoder() {

        }

        public static function init():void{

            ranChars = String("qwertyuiopasdfghjklzxcvbnm").split("")

            charsTable = new Hash({
                "0": "x",
                "1": "f",
                "2": "q",
                "3": "z",
                "4": "a",
                "5": "o",
                "6": "n",
                "7": "p",
                "8": "w",
                "9": "y"

            });

        }

        public static function encodeScore(_s:Number):String{

            var _fin:String = "";

            var scores:String = addLeadingZeros(_s);
            for(var i:uint = 0; i< scores.length; i++){
                //trace( scores.charAt(i) + " - > " + charsTable[ scores.charAt(i) ] );
                _fin += charsTable[ scores.charAt(i) ];
            }

            return _fin;

        }

        public static function decodeScore(_s:String):String{

            var _fin:String = "";

            var decoded:String = _s;

            for(var i:uint = 0; i< decoded.length; i++){
                //trace( decoded.charAt(i) + " - > "  + charsTable.getKey( decoded.charAt(i) ) );
                _fin += charsTable.getKey( decoded.charAt(i) );
            }

            return _fin;

        }

        public static function encodeScoreRand(_s:Number):String{
            var _fin:String = "";

            _fin += generateRandomChars(10) + encodeScore(_s) + generateRandomChars(3)

            return _fin;
        }

        public static function decodeScoreRand(_s:String):Number{

            var decodedString:String = _s;
            var decoded:Number;

            decodedString = decodedString.substring(10,13);         
            decodedString = decodeScore(decodedString);

            decoded = Number(decodedString);

            return decoded;
        }

        public static function generateRandomChars(_length:Number):String{

            var newRandChars:String = "";

            for(var i:uint = 0; i< _length; i++){
                newRandChars+= ranChars[ Math.ceil( Math.random()*ranChars.length-1 )];
            }

            return newRandChars;
        }

        private static function addLeadingZeros(_s:Number):String{

            var _fin:String;

            if(_s < 10 ){
                 _fin = "00" + _s.toString();
            }

            if(_s >= 10 && _s < 99 ) {
                 _fin = "0" + _s.toString();
            }

            if(_s >= 100 ) {
                _fin = _s.toString();
            }           

            return _fin;
        }


    }//end
}

ثم أقوم بإرسال المتغير مع vars وهمية أخرى ويضيع في الطريق ...إنها لعبة فلاش صغيرة تتطلب الكثير من العمل، ولكن عندما يتعلق الأمر بالجوائز، يصبح بعض الأشخاص جشعين.إذا كنت بحاجة إلى أي مساعدة، اكتب لي PM.

في صحتك، ايكو

سيكون التشفير باستخدام مفتاح قابل للعكس معروف (خاص) هو أبسط طريقة.أنا لست مهتمًا بـ AS لذلك لست متأكدًا من أنواع موفري التشفير الموجودين.

ولكن يمكنك تضمين متغيرات مثل طول اللعبة (المشفرة مرة أخرى) وعدد النقرات.

كل الأشياء مثل هذا يستطيع يجب أن تتم هندستها بشكل عكسي، لذا فكر في إضافة مجموعة من البيانات غير المرغوب فيها لإبعاد الناس عن الرائحة.

يحرر:قد يكون من المفيد المشاركة في بعض جلسات PHP أيضًا.ابدأ الجلسة عندما ينقرون على بدء اللعبة و(كما يقول التعليق على هذا المنشور) قم بتسجيل الوقت.عندما يرسلون النتيجة، يمكنك التحقق من أنهم قد حصلوا بالفعل على لعبة مفتوحة وأنهم لا يرسلون النتيجة مبكرًا جدًا أو كبيرة جدًا.

قد يكون من المفيد حساب عدد قياسي لمعرفة الحد الأقصى للنتيجة لكل ثانية/دقيقة من اللعب.

لا يمكن التحايل على أي من هذه الأشياء، لكن من المفيد أن يكون لديك بعض المنطق ليس في الفلاش حيث يمكن للأشخاص رؤيته.

من خلال تجربتي، من الأفضل التعامل مع هذه المشكلة على أنها مشكلة هندسة اجتماعية وليس مشكلة برمجة.بدلًا من التركيز على جعل الغش مستحيلًا، ركز على جعله مملًا عن طريق إزالة حوافز الغش.على سبيل المثال، إذا كان الحافز الرئيسي هو الحصول على درجات عالية مرئية علنًا، فإن مجرد تأخير ظهور النتائج العالية يمكن أن يقلل بشكل كبير من الغش عن طريق إزالة حلقة ردود الفعل الإيجابية للغشاشين.

لا يمكنك الوثوق بأي بيانات يعودها العميل.يجب إجراء التحقق من جانب الخادم.أنا لست مطور ألعاب، لكني أصنع برامج أعمال.في كلتا الحالتين، يمكن استخدام المال وسيقوم الأشخاص بكسر تقنيات التشويش من جانب العميل.

ربما يتم إرسال البيانات مرة أخرى إلى الخادم بشكل دوري وإجراء بعض التحقق من الصحة.لا تركز على كود العميل، حتى لو كان هذا هو المكان الذي يوجد فيه تطبيقك.

عندما يعتمد نظام أعلى الدرجات الخاص بك على حقيقة أن تطبيق Flash يرسل بيانات عالية الدرجات غير مشفرة/غير موقعة عبر الشبكة، والتي يمكن اعتراضها ومعالجتها/إعادة تشغيلها.والجواب يترتب على ذلك:تشفير (لائق!) أو التوقيع على بيانات أعلى الدرجات بشكل مشفر.هذا، على الأقل، يجعل من الصعب على الأشخاص كسر نظام أعلى الدرجات الخاص بك لأنهم سيحتاجون إلى استخراج المفتاح السري من ملف SWF الخاص بك.من المحتمل أن يستسلم الكثير من الناس هناك.من ناحية أخرى، كل ما يتطلبه الأمر هو شخص واحد لاستخراج المفتاح ووضعه في مكان ما.

تتضمن الحلول الحقيقية مزيدًا من التواصل بين تطبيق Flash وقاعدة بيانات أعلى الدرجات حتى تتمكن الأخيرة من التحقق من أن النتيجة المعينة واقعية إلى حد ما.ربما يكون هذا الأمر معقدًا اعتمادًا على نوع اللعبة التي لديك.

لا توجد طريقة لجعله غير قابل للاختراق تمامًا، حيث أنه من السهل فك ملفات SWF، ويمكن للمتسلل الماهر بعد ذلك تتبع التعليمات البرمجية الخاصة بك والتوصل إلى كيفية تجاوز أي نظام مشفر قد تستخدمه.

إذا كنت تريد ببساطة منع الأطفال من الغش عبر استخدام أدوات بسيطة مثل TamperData، فيمكنك إنشاء مفتاح تشفير تمرره إلى SWF عند بدء التشغيل.ثم استخدم شيئًا مثل http://code.google.com/p/as3crypto/ لتشفير النتيجة العالية قبل إعادتها إلى كود PHP.ثم قم بفك تشفيرها في نهاية الخادم قبل تخزينها في قاعدة البيانات.

أنت تتحدث عما يسمى بمشكلة "ثقة العميل".لأن العميل (في هذا المبلغ النقدي، هو ملف SWF الذي يتم تشغيله في المتصفح) يفعل شيئًا مصممًا للقيام به.حفظ درجة عالية.

تكمن المشكلة في أنك تريد التأكد من أن طلبات "حفظ النتيجة" تأتي من فيلم الفلاش الخاص بك، وليس من بعض طلبات HTTP التعسفية.الحل المحتمل لذلك هو تشفير الرمز المميز الذي أنشأه الخادم في ملف SWF في وقت الطلب (باستخدام FLAM) التي يجب أن تصاحب الطلب لحفظ درجة عالية.بمجرد قيام الخادم بحفظ هذه النتيجة، تنتهي صلاحية الرمز المميز ولن يعد من الممكن استخدامه للطلبات.

الجانب السلبي لهذا هو أن المستخدم لن يتمكن إلا من إرسال درجة عالية واحدة لكل تحميل لفيلم الفلاش - يجب عليك إجباره على تحديث/إعادة تحميل ملف SWF قبل أن يتمكن من اللعب مرة أخرى للحصول على نتيجة جديدة.

عادةً ما أقوم بتضمين "بيانات شبحية" لجلسة اللعبة مع إدخال أعلى الدرجات.لذا، إذا كنت أقوم بإنشاء لعبة سباق، أقوم بتضمين بيانات إعادة التشغيل.غالبًا ما تكون لديك بيانات إعادة التشغيل بالفعل لوظيفة إعادة التشغيل أو وظيفة سباق الأشباح (اللعب ضد سباقك الأخير، أو اللعب ضد شبح المتأنق رقم 14 على لوحة المتصدرين).

يعد التحقق من ذلك عملاً يدويًا للغاية، ولكن إذا كان الهدف هو التحقق مما إذا كانت أفضل 10 إدخالات في المسابقة شرعية، فقد يكون هذا إضافة مفيدة إلى ترسانة الإجراءات الأمنية التي أشار إليها الآخرون بالفعل.

إذا كان الهدف هو الاحتفاظ بقائمة النتائج العالية على الإنترنت حتى نهاية الوقت دون أن يضطر أي شخص إلى الاطلاع عليها، فلن يجلب لك هذا الكثير.

الطريقة التي يقوم بها نظام arcade الشهير الجديد هي إرسال البيانات من الفلاش إلى php، ثم العودة إلى الفلاش (أو إعادة تحميله)، ثم العودة إلى php.يتيح لك هذا القيام بأي شيء تريده لمقارنة البيانات بالإضافة إلى تجاوز عمليات اختراق البيانات/فك التشفير وما شابه.إحدى الطرق للقيام بذلك هي تعيين قيمتين عشوائيتين من php إلى الفلاش (والتي لا يمكنك الحصول عليها أو رؤيتها حتى في حالة تشغيل ملتقط بيانات فلاش في الوقت الفعلي)، باستخدام صيغة رياضية لإضافة النتيجة مع القيم العشوائية ثم التحقق منها باستخدام نفس الصيغة لعكسها لمعرفة ما إذا كانت النتيجة تطابقها عندما تنتقل أخيرًا إلى PHP في النهاية.لا تكون هذه القيم العشوائية مرئية أبدًا، كما أنها تحدد أيضًا توقيت حدوث المعاملة، وإذا كانت أكثر من بضع ثوانٍ، فإنها تضع علامة عليها أيضًا على أنها غش لأنها تفترض أنك أوقفت الإرسال لمحاولة اكتشاف القيم العشوائية أو تشغيلها الأرقام من خلال نوع ما من التشفير لإرجاع القيم العشوائية المحتملة للمقارنة مع قيمة النتيجة.

يبدو هذا حلاً جيدًا جدًا إذا سألتني، هل يرى أي شخص أي مشكلات في استخدام هذه الطريقة؟أو الطرق الممكنة حول ذلك؟

أعتقد أن أبسط طريقة هي إجراء مكالمات إلى وظيفة مثل RegisterScore(score) في كل مرة تسجل فيها اللعبة نتيجة لإضافتها ثم تشفيرها وتعبئتها وإرسالها إلى برنامج نصي php كسلسلة.سيعرف برنامج PHP النصي كيفية فك تشفيره بشكل صحيح.سيؤدي هذا إلى إيقاف أي مكالمات مباشرة إلى البرنامج النصي php لأن أي محاولة لفرض نتيجة قد تؤدي إلى خطأ في إلغاء الضغط.

ولا يمكن ذلك إلا بالمحافظة على كل منطق اللعبة في جانب الخادم والذي يقوم أيضًا بتخزين النتيجة داخليًا دون علم المستخدم.لأسباب اقتصادية وعلمية، لا يمكن للبشرية تطبيق هذه النظرية على جميع أنواع الألعاب باستثناء ألعاب تبادل الأدوار.على سبيل المثال.يعد الاحتفاظ بالفيزياء من جانب الخادم أمرًا مكلفًا من الناحية الحسابية ويصعب الاستجابة له مثل سرعة اليد.حتى أنه من الممكن، أثناء لعب الشطرنج، يمكن لأي شخص مطابقة أسلوب لعب الشطرنج القائم على الذكاء الاصطناعي مع خصمه.لذلك، أفضل ألعاب متعددة اللاعبين يجب أن تحتوي أيضًا على الإبداع عند الطلب.

ليس من الممكن حقًا تحقيق ما تريد.يمكن دائمًا الوصول جزئيًا إلى الأجزاء الداخلية لتطبيق Flash، خاصة عندما تعرف كيفية استخدام أشياء مثل محرك الغش, ، مما يعني أنه بغض النظر عن مدى أمان اتصالات موقع الويب والمتصفح<->الخادم، فسيظل التغلب على ذلك أمرًا بسيطًا نسبيًا.

قد تكون فكرة جيدة التواصل مع الواجهة الخلفية عبر AMFPHP.يجب أن يمنع الكسالى على الأقل من محاولة دفع النتائج عبر وحدة تحكم المتصفح.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top