openssl_encrypt
openssl_encrypt($data, $cipher_algo, $passphrase, $options = 0, $iv = "", &$tag = null, $aad = "", $tag_length = 16)
Szyfruje dane wybranym szyfrem i kluczem. Do nowych danych nadaje się aes-256-gcm: szyfruje i dodaje jeszcze tag uwierzytelniający, dzięki czemu odszyfrowanie rozpozna, czy ktoś zmienił dane. Zwraca zaszyfrowane dane (bez opcji OPENSSL_RAW_DATA w base64), przy błędzie false.
Parametry
- $data – tekst do zaszyfrowania.
- $cipher_algo – nazwa szyfru:
aes-256-gcm(zalecany),aes-256-cbc,chacha20-poly1305… - $passphrase – klucz: losowe bajty właściwej długości (32 bajty dla AES-256), nie hasło.
- $options –
OPENSSL_RAW_DATA= zwrócić dane binarne zamiast base64. - $iv – wektor inicjujący: przy każdym szyfrowaniu nowy losowy, długość zwraca
openssl_cipher_iv_length(). - &$tag – przy GCM funkcja zapisze tu tag uwierzytelniający (potrzebny do odszyfrowania); $aad – dane, które są sprawdzane, ale nie szyfrowane.
Przykłady
// klucz: 32 losowe bajty, zapisane poza bazą danych (w .env albo konfiguracji)
$key = random_bytes(32);
$iv = random_bytes(openssl_cipher_iv_length("aes-256-gcm"));
$encrypted = openssl_encrypt("Paszport nr 123456789", "aes-256-gcm", $key, OPENSSL_RAW_DATA, $iv, $tag);
echo strlen($iv) . " " . strlen($tag); // 12 16
// IV, tag i szyfrogram zapisz w bazie danych (ani IV, ani tag nie są tajne)
$stored = base64_encode($iv . $tag . $encrypted);
// odszyfrowanie
$data = base64_decode($stored);
echo openssl_decrypt(substr($data, 28), "aes-256-gcm", $key, OPENSSL_RAW_DATA, substr($data, 0, 12), substr($data, 12, 16)); // Paszport nr 123456789
Na co uważać
- Przy GCM nigdy nie używaj tego samego IV dwa razy z tym samym kluczem – to zdradza treść obu wiadomości. IV bierz zawsze z
random_bytes(). - Nie używaj hasła bezpośrednio jako klucza. Klucz wyprowadza się z hasła przez
hash_pbkdf2()albosodium_crypto_pwhash()z losową solą. - Tryb
aes-256-cbcnie ma uwierzytelniania – bez własnego HMAC atakujący może zmienić szyfrogram. Trybu ECB (aes-256-ecb) do prawdziwych danych nie używaj. - Haseł użytkowników się nie szyfruje, tylko hashuje (
password_hash()) – szyfrowanie jest dla danych, które trzeba znowu odczytać.
Powiązane funkcje:
openssl_decrypt()
openssl_cipher_iv_length()
random_bytes()
sodium_crypto_secretbox()
hash_pbkdf2()
base64_encode()