문제

업데이트 (솔루션)

이 게시물이 괜찮은 관심을받는 것처럼 보이므로 솔루션이 적절한 것을 제공하는 것이 끝났다는 것을 알려 드리고자합니다. enctype (콘텐츠 유형) 매개 변수 <FORM> 선언. 값을 설정해야합니다 multipart/form-data 기본 Enctype를 사용하여 발생하는 인코딩을 방지합니다. application/x-www-form-urlencoded. 아래에서 작은 발췌 HTML 문서의 양식 w3.org :

콘텐츠 유형 "Application/X-WWW-FORM-URLENCODED"는 대량의 이진 데이터 또는 비 ASCII 문자를 포함하는 텍스트를 전송하는 데 비효율적입니다. 콘텐츠 유형 "multipart/form-data"는 파일, 비 ASCII 데이터 및 이진 데이터를 포함하는 양식을 제출하는 데 사용해야합니다.

그리고 여기에 적절한 양식 선언이 있습니다.

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

초기 질문

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