Start · Sprachen · PHP · Referenz · openssl_private_encrypt

openssl_private_encrypt

Funktion

Verschlüsselt Daten mit einem privaten RSA-Schlüssel (typischerweise für digitale Signaturen oder Nachweiszwecke).

seit PHP 4.0.6 Kategorie: crypto

Signatur

openssl_private_encrypt(string $data, string &$encrypted_data, OpenSSLAsymmetricKey|array|string $private_key, int $padding = OPENSSL_PKCS1_PADDING): bool

Beschreibung

openssl_private_encrypt() verschlüsselt den Inhalt von $data mit dem angegebenen privaten RSA-Schlüssel und schreibt das Ergebnis in die Variable $encrypted_data. Die Funktion nutzt RSA-Verschlüsselung mit privatem Schlüssel, was im Grunde dem Signiervorgang entspricht: Nur der Inhaber des privaten Schlüssels kann die Daten verschlüsseln, und jeder mit dem zugehörigen öffentlichen Schlüssel kann sie entschlüsseln (via openssl_public_decrypt()).

Der typische Anwendungsfall ist das Erstellen von Nachweisen oder einfacher digitaler Signaturen, bei denen sichergestellt werden soll, dass Daten vom Besitzer des privaten Schlüssels stammen. Für kryptografisch robuste Signaturen sollte jedoch openssl_sign() bevorzugt werden, da diese Funktion zusätzlich einen Hash-Algorithmus anwendet.

Die Länge der zu verschlüsselnden Daten ist durch die Schlüsselgröße begrenzt. Bei einem 2048-Bit-RSA-Schlüssel und OPENSSL_PKCS1_PADDING dürfen die Eingabedaten maximal 245 Bytes betragen. Größere Datenmengen müssen aufgeteilt oder symmetrisch verschlüsselt werden (Hybrid-Verschlüsselung).

  • OPENSSL_PKCS1_PADDING: Standard-Padding gemäß PKCS#1 v1.5 (Standard und weit verbreitet).
  • OPENSSL_NO_PADDING: Kein Padding — nur für spezielle Protokolle geeignet, ansonsten unsicher.

Parameter

Name Typ Default Beschreibung
$data Pflicht string Die Klartextdaten, die verschlüsselt werden sollen. Die maximale Länge hängt von der Schlüsselgröße und dem Padding-Modus ab.
$encrypted_data Pflicht string Ausgabeparameter (Referenz), in den die verschlüsselten Binärdaten geschrieben werden. Der vorherige Inhalt wird überschrieben.
$private_key Pflicht OpenSSLAsymmetricKey|array|string Der private Schlüssel als OpenSSLAsymmetricKey-Ressource (aus openssl_get_privatekey()), als PEM-kodierter String oder als Array [PEM-String, Passphrase] für passwortgeschützte Schlüssel.
$padding int OPENSSL_PKCS1_PADDING Padding-Modus: OPENSSL_PKCS1_PADDING (Standard, empfohlen) oder OPENSSL_NO_PADDING (nur für Spezialfälle).

Rückgabewert

Typ
bool
Beschreibung
Gibt true zurück, wenn die Verschlüsselung erfolgreich war, andernfalls false. Im Fehlerfall (z. B. ungültiger Schlüssel oder zu große Datenmenge) liefert die Funktion false und es können Fehlermeldungen über openssl_error_string() abgerufen werden.

Beispiele

Einfache Datenverschlüsselung mit privatem Schlüssel und Entschlüsselung mit öffentlichem Schlüssel

<?php
// Schlüsselpaar erzeugen
$keyPair = openssl_pkey_new([
    'private_key_bits' => 2048,
    'private_key_type' => OPENSSL_KEYTYPE_RSA,
]);

// Privaten Schlüssel exportieren
openssl_pkey_export($keyPair, $privateKeyPem);

// Öffentlichen Schlüssel exportieren
$publicKeyDetails = openssl_pkey_get_details($keyPair);
$publicKeyPem = $publicKeyDetails['key'];

$originalData = 'Geheime Nachricht vom Server';
$encrypted = '';

// Mit privatem Schlüssel verschlüsseln
if (openssl_private_encrypt($originalData, $encrypted, $privateKeyPem)) {
    echo 'Verschlüsselung erfolgreich.' . PHP_EOL;
    echo 'Verschlüsselte Länge: ' . strlen($encrypted) . ' Bytes' . PHP_EOL;
} else {
    echo 'Fehler: ' . openssl_error_string() . PHP_EOL;
    exit(1);
}

// Mit öffentlichem Schlüssel entschlüsseln
$decrypted = '';
if (openssl_public_decrypt($encrypted, $decrypted, $publicKeyPem)) {
    echo 'Entschlüsselt: ' . $decrypted . PHP_EOL;
} else {
    echo 'Entschlüsselung fehlgeschlagen.' . PHP_EOL;
}
Verschlüsselung erfolgreich. Verschlüsselte Länge: 256 Bytes Entschlüsselt: Geheime Nachricht vom Server

Passwortgeschützter privater Schlüssel und Base64-Ausgabe

<?php
// Privaten Schlüssel mit Passphrase laden
$privateKeyPem = file_get_contents('/pfad/zum/private.key');
$passphrase = 'meinPasswort123';

$privateKey = openssl_get_privatekey($privateKeyPem, $passphrase);

if ($privateKey === false) {
    die('Schlüssel konnte nicht geladen werden: ' . openssl_error_string());
}

$data = 'Token:' . time();
$encrypted = '';

if (openssl_private_encrypt($data, $encrypted, $privateKey)) {
    // Für Übertragung als Base64 kodieren
    $base64Encrypted = base64_encode($encrypted);
    echo 'Verschlüsselt (Base64): ' . $base64Encrypted . PHP_EOL;

    // Schlüssel-Ressource freigeben
    openssl_free_key($privateKey);
} else {
    echo 'Fehler beim Verschlüsseln: ' . openssl_error_string() . PHP_EOL;
}
Verschlüsselt (Base64): [Base64-kodierter verschlüsselter String]

// Wichtig · Fallstricke

Sicherheitshinweis: openssl_private_encrypt() ist keine Methode zur vertraulichen Verschlüsselung von Daten gegenüber einem Empfänger — dafür ist openssl_public_encrypt() (mit dem öffentlichen Schlüssel des Empfängers) zu verwenden. Die Verschlüsselung mit dem privaten Schlüssel bietet keine Vertraulichkeit, da jeder mit dem öffentlichen Schlüssel die Daten entschlüsseln kann.

Für digitale Signaturen sollte openssl_sign() bevorzugt werden, da diese Funktion intern einen kryptografisch sicheren Hash (z. B. SHA-256) auf die Daten anwendet, bevor diese signiert werden. openssl_private_encrypt() signiert die Rohdaten ohne vorheriges Hashing, was bei größeren Datenmengen problematisch ist.

OPENSSL_NO_PADDING sollte nur in sehr speziellen, gut verstandenen Protokollen eingesetzt werden. Ohne Padding ist RSA anfällig für verschiedene Angriffe (z. B. Chosen-Plaintext-Angriffe).

Ab PHP 8.0 gibt die Funktion ein OpenSSLAsymmetricKey-Objekt zurück (statt einer Ressource); openssl_free_key() ist seit PHP 8.0 veraltet (no-op) und kann weggelassen werden.