سؤال

تحديث (حل)

نظرا لأن هذا المنصب يبدو أنه يحصل على كمية لائقة من الاهتمام، أود أن أخبرك أن الحل انتهى الأمر إلى توفير مناسب enctype (نوع المحتوى) المعلمة في <FORM> تصريح. يجب عليك تعيين القيمة إلى multipart/form-data لمنع الترميز الذي سيعقد بشكل خلاف ذلك باستخدام Enctype الافتراضي application/x-www-form-urlencoded. وبعد مقتطفات صغيرة أدناه أشكال في مستندات HTML في W3.ORG:

نوع المحتوى "تطبيق / X-NOW WWW-FORM-ROLLECODED" غير فعال لإرسال كميات كبيرة من البيانات الثنائية أو النص الذي يحتوي على أحرف غير ASCII. يجب استخدام نوع المحتوى "بيانات متعددة النماذج" لتقديم النماذج التي تحتوي على ملفات وبيانات غير ASCII والبيانات الثنائية.

وهنا إعلان النموذج المناسب:

<FORM method="POST" action="/path/to/file/" name="encryptedForm" enctype="multipart/form-data">

السؤال الأول

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

/**
 * Two way encryption function to encrypt/decrypt keys with
 * the DES encryption algorithm.
 */
public static function encryption($text, $encrypt = true)
{
    $encrypted_data = '';
    $td = mcrypt_module_open('des', '', 'ecb', '');
    $iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
    if (mcrypt_generic_init($td, substr(self::$randomizer, 16, 8), $iv) != -1) {
        if ($encrypt) {
            // attempt to sanitize encryption for use as a form element name
            $encrypted_data = mcrypt_generic($td, $text);
            $encrypted_data = base64_encode($encrypted_data);
            $encrypted_data = 'i' . strtr($encrypted_data, '+/=', '-_.');
            self::$encrypted[] = $encrypted_data;
        } else {
            // reverse form element name sanitization and decrypt
            $text = substr($text, 1);
            $text = strtr($text, '-_.', '+/=');
            $text = base64_decode($text);
            $encrypted_data = mdecrypt_generic($td, $text);
        }
        mcrypt_generic_deinit($td);
        mcrypt_module_close($td);
    }
    return $encrypted_data;
}

أقوم لاحقا بإجراء مكالمة إعداد قيمة عنصر نموذج مخفي باستخدام:

base64_encode(serialize(self::$encrypted))

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

    // load the mapping entry
    $encrypted_fields = $input->post('encrypted', '');
    if (empty($encrypted_fields)) {
        throw new AppException('The encrypted form field was empty.');
    }

    // decompress array of encrypted fields
    $encrypted_fields = @unserialize(base64_decode($encrypted_fields));
    if ($encrypted_fields === false) {
        throw new AppException('The encrypted form field was not valid.');
    }

    // get the mapping of encrypted keys to key
    $data = array();
    foreach ($_POST as $key => $val) {
        // if the key is encrypted, add to data array decrypted
        if (in_array($key, $encrypted_fields)) {
            $decrypted = self::encryption($key, false);
            $data[$decrypted] = $val;
            unset($_POST[$key]);
        } else {
            $data[$key] = $val;
        }
    }

    // merge $_POST array with decrypted key array
    $_POST += $data;

محاولاتي لفك تشفير مفاتيح حقل النموذج المشفرة فشلت. إنه ببساطة إنشاء مفتاح مشوه جديد في $_POST مجموعة مصفوفة. تخميني هو إما base64_encoding أو serialization هو تجريد الأحرف من $encrypted_data. يمكن أن يتحقق شخص ما إذا كان هذا هو الجاني وما إذا كانت هناك أي طرق بديلة لمفاتيح تشفير النماذج؟

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

المحلول

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

<?php
    /**
     * Two way encryption function to encrypt/decrypt keys with
     * the DES encryption algorithm.
     */
    function encryption($text, $encrypt = true, &$encryptedFields = array())
    {
        $encrypted_data = '';
        $td = mcrypt_module_open('des', '', 'ecb', '');
        $iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
        if (mcrypt_generic_init($td, substr('sdf234d45)()*5gf512/?>:LPIJ*&U%&^%NBVFYUT^5hfhgvkjtIUUYRYT', 16, 8), $iv) != -1) {
            if ($encrypt) {
                // attempt to sanitize encryption for use as a form element name
                $encrypted_data = mcrypt_generic($td, $text);
                $encrypted_data = base64_encode($encrypted_data);
                $encrypted_data = 'i' . strtr($encrypted_data, '+/=', '-_.');
                //self::$encrypted[] = $encrypted_data;
                $encryptedFields[] = $encrypted_data;
            } else {
                // reverse form element name sanitization and decrypt
                $text = substr($text, 1);
                $text = strtr($text, '-_.', '+/=');
                $text = base64_decode($text);
                $encrypted_data = mdecrypt_generic($td, $text);
            }
            mcrypt_generic_deinit($td);
            mcrypt_module_close($td);
        }
        return $encrypted_data;
    }

    $encryptedFields = array();

    // encrypt some form fields
    encryption('firstname', true, $encryptedFields);
    encryption('lastname', true, $encryptedFields);
    encryption('email_fields', true, $encryptedFields);

    echo "Encrypted field names:\n";
    print_r($encryptedFields);

    // create a usable string of the encrypted form fields
    $hiddenFieldStr = base64_encode(serialize($encryptedFields));

    echo "\n\nFull string for hidden field: \n";
    echo $hiddenFieldStr . "\n\n";


    $encPostFields = unserialize(base64_decode($hiddenFieldStr));

    echo "\n\nDecrypted field names:\n";
    foreach($encPostFields as $field)
    {
        echo encryption($field, false)."\n";
    }
    ?>
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top