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() albo sodium_crypto_pwhash() z losową solą.
  • Tryb aes-256-cbc nie 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()