Libsodium nie jest wbudowane w MySQL, więc nie możesz po prostu wywołać czegoś równoważnego AES_ENCRYPT()
z poziomu zapytania MySQL i uzyskaj oczekiwane wyniki.
Alternatywnym podejściem jest jednak użycie biblioteki takiej jak CipherSweet , który zapewnia uwierzytelnione szyfrowanie z możliwością wyszukiwania. Upewnij się, że rozumiesz jego funkcje i ograniczenia zanim zdecydujesz się go użyć.
<?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);
Powinieneś zobaczyć coś podobnego do tego. Wartości w [0]
zmieni się, ale wartości w [1]
nie będzie. Dzieje się tak, ponieważ [0]
zawiera dane wiersza z (niektóre pola są zaszyfrowane). [1]
zawiera tylko ślepe indeksy (do wykorzystania później w zapytaniach 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"
}
}
}
Zwróć uwagę, że pola zmiennoprzecinkowe zawsze będą generować dane wyjściowe o stałej długości, nawet jeśli dane wejściowe mają różne poziomy dokładności. Odbywa się to celowo, aby uniemożliwić atakującym poznanie informacji z długości zaszyfrowanego tekstu.
Jeśli wybierzesz ModernCrypto
zamiast FIPSCrypto
, wszystko powyższe zostanie wykonane za pomocą libsodium. Dokładne szyfrowanie używane przez każdy z nich jest udokumentowane tutaj
, jeśli ktoś jest ciekawy.
Zauważ, że będziesz musiał wykonać własne obliczenia odszyfrowanych wartości w PHP, a nie w SQL.
W końcu cały sens szyfrowania danych przed przechowywaniem ich w bazie danych polega na ukryciu ich przed serwerem bazy danych (i wszystkimi atakującymi, którzy mogli włamać się na ten serwer).