base64 kodlama ve serileştirme ile mcrypt 2 yönlü şifreleme sorunu

1 Cevap php

UPDATE (SOLUTION)

Bu mesaja dikkat yeterli miktarda almak gibi görünüyor beri, ben size çözüm <FORM> uygun bir enctype (içerik türü) parametresini sağlamak için varlık sona erdi olduğunu bildirmek isterim beyanı. Sen multipart/form-data aksi application/x-www-form-urlencoded varsayılan EncType kullanarak yer alacağını kodlama önlemek için değerini ayarlamanız gerekir. Aşağıdaki Forms in HTML Documents w3.org de küçük bir alıntı:

The content type "application/x-www-form-urlencoded" is inefficient for sending large quantities of binary data or text containing non-ASCII characters. The content type "multipart/form-data" should be used for submitting forms that contain files, non-ASCII data, and binary data.

Ve burada uygun FORMU bildirimi:

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

INITIAL QUESTION

Ben aslında mcrypt kullanarak şifrelenmiş bir değer form alan adlarını değiştirir formu spam koruma sınıfı üzerinde çalışıyorum. Bu sorun mcrypt şifreleme form alanları geçersiz olur sadece alfanümerik karakter ile sınırlı olmasıdır. Given the code below, can you think of any reason why I'd be having problems decrypting the values of the already encrypted array?

/**
 * 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;
}

Daha sonra kullanarak gizli bir form elemanın değerini belirleyen bir arama yapmak:

base64_encode(serialize(self::$encrypted))

Esasen gizli alan şifrelenmiş değeri ile şifrelenmiş tüm form alanları bir dizi içerir. Bu yüzden alanları backend şifresi gerekir ki biliyorum. Form sunulması üzerine bu alan aşağıdaki kod ile arka uç derlenecek:

    // 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;

Şifreli form alanı anahtarları şifresini benim girişimleri başarısız oluyor. Bu sadece $_POST diziye yeni bir bozuk anahtar yaratıyor. Benim tahminim ya base64_encoding veya serialization $encrypted_data adlı karakter stripping. Could somebody verify if this is the culprit and whether there are any alternative methods for encoding form keys?

1 Cevap

Yani kodunuzu aldı ve ben bir post isteği elemanı kaldırmak ve fonksiyon iyi çalışıyor gibi görünüyor, böylece o biraz değiştirilmiş. Eğer ben yayınlanmıştır kodunu almak ve onunla bir komut dosyası oluşturursanız, bu cli çalışmalı ve doğru alanları şifresini / onun şifreleniyor görürsünüz. Bu mesaja istek olduğu anlamına olurdu bazı nasıl şifreli / tefrika / kodlanmış verileri tahrifine. Bir çerçeve kullanıyorsanız, ben onları eşleşmiyor için neden anahtarları / değerleri değiştirmek olabilir gibi sonrası dizi nasıl işleyeceğini daha fazla olmazdı. Deftere kod iyi görünüyor.

<?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";
    }
    ?>