Шифрование get запроса php

PHP — знак плюс с запросом GET

У меня есть скрипт PHP, который выполняет базовое шифрование строки с помощью метода ниже:

 if ($_GET['method'] == "encrypt") < $output= base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, md5($key), $string, MCRYPT_MODE_CBC, md5(md5($key)))); >echo $output; ?> 

Пример URL для шифрования строки будет выглядеть следующим образом:

Encrypt.php? Method=encrypt&str= быстрый лис

Который возвратил бы это как зашифрованную строку:

LCuT / ieVa6cl3 / 4VtzE + jd9QPT3kvHYYJFqG6tY3P0Q =

Теперь, чтобы расшифровать строку, все, что вам нужно сделать, это изменить запрос «method» на «decrypt», вот так:

Encrypt.php? Метод = дешифровать & ул =LCuT/ieVa6cl3/4VtzE+jd9QPT3kvHYYJFqG6tY3P0Q=

Единственная проблема заключается в том, что когда эта зашифрованная строка расшифровывается, она возвращает это:

Я сузил проблему до знака плюс, который находится в зашифрованной строке. Похоже, что PHP-метод GET переводит знак плюс в пустое пространство. Я искал эту ошибку и обнаружил, что она уже была зарегистрирована здесь. Я пробовал разные методы, перечисленные на этой странице и другие, но безуспешно. Самое близкое, что я получил, это:

$fixedstring = str_replace(" ", "+", $string); 

и затем, используя $fixedstring в методах шифрования, проблема заключается в том, что при расшифровке все пробелы преобразуются в знаки плюс. Есть идеи?

Я знаю, что использование POST имело бы больше смысла, но я использую GET по определенным причинам. Я пощажу детали.

Источник

Don’t.

Cryptography is a tricky field, especially for newcomers. To a security expert, it’s immediately obvious why encrypting URL parameters is a bad idea. Let me explain why, and then I’ll offer a superior alternative solution.

Why Encrypting URL Parameters is a Bad Idea

Typically, the desired result of encrypting a URL looks like this:

A bad design

One problem arises that, given the desired outcome of a very short URL (which is a common constraint to any system that sends URLs over SMS), there isn’t enough room to both encrypt the desired information and then authenticate the encrypted output. Encryption without message authentication is totally broken.

Unless you’re a cryptographer or security engineer, you wouldn’t know these details. In this situation, encryption adds complexity and lots of room for nefarious errors to your application, for no real benefit. Obfuscation is a trivial task, as we’ll demonstrate below; why add unnecessary complexity if you can avoid it?

What About Hashids?

Do not encode sensitive data. This includes sensitive integers, like numeric passwords or PIN numbers. This is not a true encryption algorithm.

This might seem like an attractive solution, but it won’t stop users from trivially teasing the underlying database row ID out of your obfuscated URL parameter. Hashids are not secure; don’t use them.

What Should I Do Instead?

Okay, by this point, we hope you’re convinced that neither encryption nor hashids are the way to go forward. Encryption is very hard to get right, and hashids are not secure.

Читайте также:  Java программирование это сложно

But knowing this doesn’t solve your problem: How can you serve content via an obfuscated URL without resorting to encryption?

The answer is: add another column to the table with a unique, random token and reference that in your database lookups instead of your database identifier.

A good design

  • In MySQL, an INTEGER(11) UNSIGNED primary key can hold about 4 billion rows. This is equal to 32 bits.
  • If you generate 9 raw bytes from a cryptographically secure pseudorandom number generator (72 bits of possible values), then base64 the result, you will end up with a 12 character identifier.
  • 72 bits of possible values means a 50% chance of collision at $2^$ records, according to the birthday problem.

This means you have a 50% chance of only two duplicate random values after about 69 billion records (a far cry beyond your 4 billion storage capacity). This means that you will almost never have a collision. You should still make sure every selector you generate is unique before inserting a new one, of course.

Furthermore, this record is completely randomly generated and has nothing to do with the rest of the data stored in your database. There is no pattern to be found. (The closest relevant buzz-word here is a «zero knowledge».)

Instead of encrypting URL parameters, add a column that stores a random 12-character string for each row (which is generated by base64-encoding 9 bytes from a CSPRNG), and use that in your URLs and SELECT queries.

use ParagonIE\ConstantTime\Base64UrlSafe; /** * Generate a selector * * @return string (12 characters) */ function generateSelector(): string < return Base64UrlSafe::encode(random_bytes(9)); /* Equivalent: return strtr(base64_encode(random_bytes(9)), '+/', '-_'); */ >

This problem is simpler and less likely to cause bugs or implementation errors now and going forward.

A Quick Note about Access Controls

An obfuscated URL does not obviate the need for access controls. The use case here is, «I want to serve a unique ID for a particular resource without leaking metadata about the activity level of our app.»

Do not use obfuscated URLs as a backdoor into your application.

But What if I Really Want to Encrypt URL Parameters?

If after seeing our above recommendation you still want to go forward with encrypting your GET parameters, don’t write your own cryptography. Use a peer-reviewed, secure PHP cryptography library instead.

Update: «How about timing attacks when selecting the token that way?»

This question was posed by Niklas Keller after the initial publication of this blog post. We feel that it’s interesting enough to answer here in detail.

Unless you know otherwise, you should generally assume that database lookups are vulnerable to timing attacks. You can design this URL obfuscation scheme in a timing-attack-resistant way, but it will result in a longer URL parameter and a little bit more application complexity. Be forewarned that fixed/random delays are not a solution for timing attacks.

The solution here is to employ split tokens (which is very similar to our secure implementation of «remember me» cookies).

Instead of adding one column ( selector above), we’re going to add two: selector and verifier . Our URLs will consist of the two concatenated together.

Читайте также:  Javascript считать до символа

When we perform a lookup, we’ll grab the first $N$ (let’s say 12) characters and feed it into the selector. If a record is found, we will pull the row then compare the remainder of our URL parameter with verifier using PHP’s hash_equals() function. If hash_equals() doesn’t return true , act like the row was not found.

Even if an attacker can use a timing side-channel on the first 12 characters of a URL, if the remaining $M$ characters (let’s say 24) are not vulnerable to timing attacks.

use ParagonIE\ConstantTime\Base64UrlSafe; /** * Generate a selector * * @param bool $skipUniqueCheck * @return string (12 characters) */ function generateSelector(bool $skipUniqueCheck = false): string < /** @var \PDO $db */ global $db; if ($skipUniqueCheck) < $selector = Base64UrlSafe::encode(random_bytes(9)); >else < $iterations = 0; do < if (++$iterations >128) < throw new RuntimeException('Unexpected high number of selector collisions.'); >$selector = Base64UrlSafe::encode(random_bytes(9)); $exists = $db->prepare("SELECT count(*) FROM users WHERE selector = ?"); $exists->execute([$selector]); > while ($exists->fetchColumn() > 0); > return $selector; > /** * Generate a validator * * @return string (24 characters) */ function generateValidator(): string < return Base64UrlSafe::encode(random_bytes(18)); >/** * Validate a URL input * * @param string $selector (string, 36 chars) * @return array * @throws Exception */ function getUserBySelector(string $selector): array < /** @var \PDO $db */ global $db; if (preg_match('/^[0-9A-Za-z\-_]$/', $selector)) < $stmt = $db->prepare("SELECT * FROM users WHERE selector = ?"); $stmt->execute([substr($selector, 0, 12)]) $user = $stmt->fetch(PDO::FETCH_ASSOC); if (!empty($user)) < if (hash_equals(substr($selector, 12), $user['validator']))) < return $user; >> > throw new Exception('Invalid URL'); > 

Since this information isn’t as sensitive as a long-term authentication token, we don’t really need to hash the verifier in the database (but there’s no harm in doing so, provided you don’t need to retrieve the full URL at will).

Conclusion

Don’t use encryption to obfuscate URL parameters. Use a random look-up instead.

Источник

Как зашифровать данные $ _GET в php?

Как и в php, мы используем $ _GET для передачи переменных в url, я хочу передать переменные, которые включают идентификатор пользователя, который я хочу быть анонимным, поэтому можно что-то сделать, чтобы зашифровать переменную перед ее передачей, а переменная после того, как на странице можно дешифровать, чтобы получить исходное значение переменной.

Перед передачей переменной $

при взятии из url и дешифрованного $

Вы можете использовать шифр RC4, если вы собираетесь шифровать / расшифровывать только на стороне сервера

Просто создайте случайные строки (убедитесь, что они уникальны) для каждой записи в базе данных и сохраните ее там. Затем используйте это как идентификатор. Обратите внимание, что это, конечно, не имеет никакого отношения к шифрованию.

Быстрый и грязный способ достичь этого (для каждого запроса)

  • на клиенте, создайте строку типа «xx: 10: yy», где xx и yy – строки, содержащие pf random characetrs
  • на клиенте, создайте соленый хэш пользователей соленый / хешированный пароль
  • используйте этот хеш в качестве ключа и строку из первой пули в виде открытого текста для шифрования, например crypt.js
  • в запросе отправьте зашифрованную строку и соль
  • на сервере используйте переданную соль, а пользовательский соленый / хешированный пароль – для восстановления ключа
  • на сервере используйте mcrypt или друзей, чтобы расшифровать строку
  • на сервере используют стандартные функции обработки текста PHP для восстановления полезной нагрузки из расшифрованной строки
Читайте также:  Php проверить есть ли свойство

Источник

Шифрование данных на PHP

От автора: в данном уроке мы с Вами рассмотрим шифрование данных стандартными средствами языка PHP. Так как при создании различных скриптов очень часто возникает задача шифрования данных. К примеру, важную информацию, которую необходимо сохранить в куках, можно зашифровать для повышения безопасности сайта.

скачать исходникискачать урок

Введение

В данном уроке мы с Вами не будем рассматривать все теоретические моменты процесса шифрования данных, так как для этого понадобиться несколько уроков. Мы изучим только основы, но их полнее будет достаточно, что бы Вы смогли зашифровать данные и выполнить их расшифровку.

Шифрование бывает двух видов: однонаправленное – когда данные можно только зашифровать, а расшифровать нельзя (к примеру, шифрование md5) и двунаправленное – когда есть возможность, как зашифровать, так и расшифровать данные. В данном уроке мы будем использовать двунаправленное шифрование. Для работы с шифрованием в языке PHP разработано расширение под названием mcrypt, которое позволяет шифровать данные используя различные алгоритмы шифрования (шифры).

PHP-разработчик с нуля

Курс «PHP-разработчик с нуля»

— Научитесь создавать сайты и веб-приложения на языке PHP.

— Изучите актуальные фреймворки Laravel, Simfony и Yii2.

— 78 часов теории и 361 час практики.

— Вы создадите 5 масштабных проектов для портфолио.

— Помощь с поиском работы или стажировки.

SQL и получение данных

Курс «SQL и получение данных»

— Освоите один из основных инструментов работы с данными.

— 20 часов теории, 32 часа практики.

— Видеолекции, вебинары, практические задания и тренажёр.

— Выполните 6 домашних работ и итоговый проект.

— Помощь с поиском работы или стажировки.

Курс веб-разработчик с нуля

Курс «веб-разработчик с нуля»

— Научитесь программировать на JavaScript и PHP.

— Сможете создавать сайты и веб-приложения.

— Сможете уверенно работать и с фронтендом, и с бэкендом веб-сервисов.

— Выполните 9 масштабных проектов для портфолио

— Помощь с поиском работы или стажировки.

Хочу сразу сказать ,что не стоит самому придумывать свой алгоритм шифрования.

Так как шифрование данных – это целая наука и при создании собственного алгоритма, Вы можете не учесть множество различных моментов. Что приведет к уязвимости зашифрованных данных и возможно к взлому их злоумышленниками. Лучше всего использовать уже готовые алгоритмы, которые очень надежны и, так сказать, проверены временем. Алгоритм шифрования – это собственно то, каким образом будут зашифрованы данные.

Каждый алгоритм поддерживает различные режимы шифрования. Режим шифрование – это метод применения блочного шифра, который позволяет преобразовать последовательность блоков исходного текста, который шифруется, в последовательность блоков зашифрованных данных. При этом при шифровании могут использоваться данные других блоков. Мы с Вами будем использовать один из лучших режимов шифрования — MCRYPT_MODE_CFB. Данный режим, еще называют режимом обратной связи по шифрованному тексту, т.е — это такой вариант использования блочного шифра, при котором для зашифровки следующего блока текста используется результат зашифровки предыдущего блока.

Полную документацию, по расширению mcrypt можно посмотреть на официальном сайте интерпретатора языка PHP, по адресу: //us3.php.net/manual/ru/book.mcrypt.php

Полный перечень всех алгоритмов шифрования можно посмотреть по следующей ссылке: //us3.php.net/manual/ru/mcrypt.ciphers.php

Ну и конечно все режимы шифрования доступны здесь: //us3.php.net/manual/ru/mcrypt.constants.php

Теперь давайте приступим к шифрованию данных.

Шифрование данных

Для начала давайте создадим небольшую форму для ввода текста, подлежащего шифрованию:

Источник

Оцените статью