Libsodium не встроен в MySQL, поэтому вы не можете просто вызвать что-то эквивалентное AES_ENCRYPT()
из запроса MySQL и получить ожидаемые результаты.
Однако альтернативный подход заключается в использованиибиблиотека типа CipherSweet , которая обеспечивает аутентифицированное шифрование с возможностью поиска.Убедитесь, что вы понимаете его особенности и ограничения , прежде чем решите его использовать.
<?php
use ParagonIE\CipherSweet\CipherSweet;
use ParagonIE\CipherSweet\EncryptedRow;
use ParagonIE\CipherSweet\Transformation\AlphaCharactersOnly;
use ParagonIE\CipherSweet\Transformation\FirstCharacter;
use ParagonIE\CipherSweet\Transformation\Lowercase;
use ParagonIE\CipherSweet\Backend\FIPSCrypto;
use ParagonIE\CipherSweet\KeyProvider\StringProvider;
$provider = new StringProvider(
// Example key, chosen randomly, hex-encoded:
'a981d3894b5884f6965baea64a09bb5b4b59c10e857008fc814923cf2f2de558'
);
$engine = new CipherSweet($provider, new FIPSCrypto());
/** @var CipherSweet $engine */
$row = (new EncryptedRow($engine, 'contacts'))
->addTextField('first_name')
->addTextField('last_name')
->addFloatField('latitude')
->addFloatField('longitude');
// Notice the ->addRowTransform() method:
$row->addCompoundIndex(
$row->createCompoundIndex(
'contact_first_init_last_name',
['first_name', 'last_name'],
64, // 64 bits = 8 bytes
true
)
->addTransform('first_name', new AlphaCharactersOnly())
->addTransform('first_name', new Lowercase())
->addTransform('first_name', new FirstCharacter())
->addTransform('last_name', new AlphaCharactersOnly())
->addTransform('last_name', new Lowercase())
);
$prepared = $row->prepareRowForStorage([
'first_name' => 'Jane',
'last_name' => 'Doe',
'latitude' => 52.52,
'longitude' => -33.106,
'extraneous' => true
]);
var_dump($prepared);
Вы должны увидеть нечто похожее на это.Значения в [0]
будут меняться, но значения в [1]
не будут.Это потому, что [0]
содержит данные строки с (некоторые поля зашифрованы).[1]
содержит только слепые индексы (можно будет использовать позже в запросах SELECT).
array(2) {
[0]=>
array(5) {
["first_name"]=>
string(141) "fips:nrtzoaxvPIOA7jPskWVwJmC0q8WJqrsnqjPh3ifNPsRd2TAx6OwTDfSiMVCXSsSRNQb_nxJlW7TbAtf5UvQRWWKTGhk_kXxpZKdnTrpjbmxi0IgstSrZ126Qz6E0_lvjew0Ygw=="
["last_name"]=>
string(137) "fips:98f5CLB24w0zSqCGPR0D2oq9wQvUwzxo_byAp6mKgMgoJkUHZX1oTtk4Cm8FXI7fsUI8HOG5sKQFGRn6cXMw1EOMGgpXZqiXEDb3jxEbg9s95d4g2NeVd4xs2tmX0xlZ0nSM"
["latitude"]=>
string(145) "fips:d3TVGfnRFlvWxbfihgHqjpXlXU3HtkCAHzM0-4f1l5dAeQf2Vk5RDDVOGMQNM09r0O4UOAub6QTyHGezQ0bWKQ5omqoYCTBJE0Uf_2DSPfO7U4dG74phaP04iFgqpJ8G41q54Kv5t54="
["longitude"]=>
string(145) "fips:IcnUnBZZOxJPYXk-F3v12O_krNb9JsexljiV4gJzgctTpxLFm7ql0tJRF7xP3wLrUtd1VyfYBf75ot7iOSIIIFqsuyKZQdI9UyKbqd87RTMsHbHgPouxgZBg1urlqpuWqbOYEFGiti4="
["extraneous"]=>
bool(true)
}
[1]=>
array(1) {
["contact_first_init_last_name"]=>
array(2) {
["type"]=>
string(13) "w6dsrxbathjze"
["value"]=>
string(16) "546b1ffd1f83c37a"
}
}
}
Обратите внимание, что поля с плавающей запятой всегда будут выводить данные фиксированной длины, даже если входные данные имеют различные уровни точности.Это сделано намеренно, чтобы не дать злоумышленникам узнать информацию из длины зашифрованного текста.
Если вы выберете ModernCrypto
вместо FIPSCrypto
, все вышеперечисленное будет выполнено с помощью libsodium.Точное шифрование, используемое каждым из них, задокументировано здесь , если кому-то интересно.
Обратите внимание, что вам придется делать свои собственные расчеты дешифрованных значений в PHP, а не в SQL..
В конце концов, весь смысл шифрования данных перед их сохранением в базе данных состоит в том, чтобы скрыть их от сервера базы данных (и любых злоумышленников, которые могли скомпрометировать указанный сервер).