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.
В конце концов, весь смысл шифрования данных перед их сохранением в базе данных заключается в том, чтобы скрыть их от сервера базы данных (и любых злоумышленников, которые могли скомпрометировать указанный сервер).
person
Scott Arciszewski
schedule
13.10.2018