mcrypt ist veraltet, was ist die Alternative?

103

Die mcrypt-Erweiterung ist veraltet wird in PHP 7.2 nach dem entsandten Kommentar entfernt werden hier . Daher suche ich nach einer alternativen Möglichkeit, Passwörter zu verschlüsseln.

Im Moment benutze ich so etwas wie

mcrypt_encrypt(MCRYPT_RIJNDAEL_128, md5($key, true), $string, MCRYPT_MODE_CBC, $iv)

Ich benötige Ihre Meinung für den besten / stärksten Weg, um Passwörter zu verschlüsseln. Das verschlüsselte Passwort sollte natürlich von PHP 7.xx unterstützt und auch entschlüsselt werden können, da meine Kunden die Möglichkeit haben möchten, ihre Passwörter wiederherzustellen, ohne ein neues zu generieren einer.

Piet
quelle
9
Warum müssen Sie Passwörter verschlüsseln / entschlüsseln? Warum sie nicht einfach mit password_hashhashen und verifizieren password_verify?
Keine Panik
3
"Das verschlüsselte Passwort sollte auch entschlüsselbar sein" - warum? klingt nicht zu sicher. Irgendein besonderer Grund?
Funk Forty Niner
24
"Weil meine Kunden die Möglichkeit haben möchten, ihre Passwörter wiederherzustellen, ohne ein neues zu generieren." - Das ist nicht sicher und sie sollten die Möglichkeit erhalten, stattdessen ihre Passwörter zurückzusetzen.
Funk Forty Niner
4
Verschlüsseln Sie keine Passwörter . Wenn der Angreifer die Datenbank erhält, erhält er auch den Verschlüsselungsschlüssel. Iterieren Sie über eine HMAC mit einem zufälligen Salz für eine Dauer von etwa 100 ms und speichern Sie das Salz mit dem Hash. Verwenden Sie Funktionen wie password_hash, PBKDF2, Bcrypt und ähnliche Funktionen. Der Punkt ist, dass der Angreifer viel Zeit damit verbringt, Passwörter mit brutaler Gewalt zu finden.
Zaph
2
Aus dem PHP-Handbuch -> Diese Funktion wurde ab PHP 7.1.0 VERRINGERT. Es wird dringend davon abgeraten, sich auf diese Funktion zu verlassen. Alternative ist Natrium -> php.net/manual/en/book.sodium.php
MarcoZen

Antworten:

47

Es wird empfohlen, Kennwörter zu hashen, damit sie nicht entschlüsselt werden können. Dies erschwert Angreifern, die möglicherweise Zugriff auf Ihre Datenbank oder Dateien erhalten haben, etwas.

Wenn Sie Ihre Daten verschlüsseln und entschlüsseln müssen, finden Sie unter https://paragonie.com/white-paper/2015-secure-php-data-encryption eine Anleitung zur sicheren Verschlüsselung / Entschlüsselung . Um diesen Link zusammenzufassen:

  • Verwenden Sie Libsodium - Eine PHP-Erweiterung
  • Wenn Sie Libsodium nicht verwenden können, verwenden Sie Defuse / PHP-Verschlüsselung - Straight PHP-Code
  • Wenn Sie Libsodium oder Defuse / PHP-Verschlüsselung nicht verwenden können, verwenden Sie OpenSSL. Auf vielen Servern ist dies bereits installiert. Wenn nicht, kann es mit --with-openssl [= DIR] kompiliert werden.
Phil
quelle
1
Sollte zuerst openssl versuchen, da es sehr häufig ist, wo libsodium nicht ist. Raw PHP sollte nicht verwendet werden, es sei denn, alle nativen Erweiterungen sind aus, wenn Frage
JSON
Obwohl openssl sehr verbreitet ist, scheint es, dass PHP 7 Libsodium für seine Kern-Kryptographie verwenden wird. securityintelligence.com/news/…
shadi
1
Beachten Sie, dass es eine Bibliothek namens Sodium-compat( github.com/paragonie/sodium_compat ) gibt, die in PHP> = 5.2.4
RaelB
30

Wie von @rqLizard vorgeschlagen , können Sie stattdessen openssl_encrypt/ openssl_decryptPHP-Funktionen verwenden, die eine viel bessere Alternative zur Implementierung von AES (The Advanced Encryption Standard) darstellen, auch als Rijndael-Verschlüsselung bekannt.

Gemäß dem folgenden Kommentar von Scott auf php.net :

Wenn Sie 2015 Code zum Verschlüsseln / Verschlüsseln von Daten schreiben, sollten Sie openssl_encrypt()und verwenden openssl_decrypt(). Die zugrunde liegende Bibliothek ( libmcrypt) wurde seit 2007 aufgegeben und arbeitet weitaus schlechter als OpenSSL (das AES-NIauf modernen Prozessoren basiert und Cache-Timing-sicher ist).

Auch MCRYPT_RIJNDAEL_256ist es nicht AES-256, es ist eine andere Variante der Rijndael-Blockchiffre. Wenn Sie möchten , AES-256in mcrypt, müssen Sie verwenden MCRYPT_RIJNDAEL_128mit einem 32-Byte - Schlüssel. OpenSSL macht deutlicher, welchen Modus Sie verwenden (dh aes-128-cbcvs aes-256-ctr).

OpenSSL verwendet auch PKCS7-Padding im CBC-Modus anstelle des NULL-Byte-Padding von mcrypt. Daher ist es wahrscheinlicher, dass mcrypt Ihren Code für Padding-Orakelangriffe anfällig macht als OpenSSL.

Wenn Sie Ihre Chiffretexte nicht authentifizieren (Encrypt Then MAC), machen Sie es schließlich falsch.

Weiterführende Literatur:

Codebeispiele

Beispiel 1

Beispiel für eine authentifizierte AES-Verschlüsselung im GCM-Modus für PHP 7.1+

<?php
//$key should have been previously generated in a cryptographically safe way, like openssl_random_pseudo_bytes
$plaintext = "message to be encrypted";
$cipher = "aes-128-gcm";
if (in_array($cipher, openssl_get_cipher_methods()))
{
    $ivlen = openssl_cipher_iv_length($cipher);
    $iv = openssl_random_pseudo_bytes($ivlen);
    $ciphertext = openssl_encrypt($plaintext, $cipher, $key, $options=0, $iv, $tag);
    //store $cipher, $iv, and $tag for decryption later
    $original_plaintext = openssl_decrypt($ciphertext, $cipher, $key, $options=0, $iv, $tag);
    echo $original_plaintext."\n";
}
?>

Beispiel 2

Beispiel für eine authentifizierte AES-Verschlüsselung für PHP 5.6+

<?php
//$key previously generated safely, ie: openssl_random_pseudo_bytes
$plaintext = "message to be encrypted";
$ivlen = openssl_cipher_iv_length($cipher="AES-128-CBC");
$iv = openssl_random_pseudo_bytes($ivlen);
$ciphertext_raw = openssl_encrypt($plaintext, $cipher, $key, $options=OPENSSL_RAW_DATA, $iv);
$hmac = hash_hmac('sha256', $ciphertext_raw, $key, $as_binary=true);
$ciphertext = base64_encode( $iv.$hmac.$ciphertext_raw );

//decrypt later....
$c = base64_decode($ciphertext);
$ivlen = openssl_cipher_iv_length($cipher="AES-128-CBC");
$iv = substr($c, 0, $ivlen);
$hmac = substr($c, $ivlen, $sha2len=32);
$ciphertext_raw = substr($c, $ivlen+$sha2len);
$original_plaintext = openssl_decrypt($ciphertext_raw, $cipher, $key, $options=OPENSSL_RAW_DATA, $iv);
$calcmac = hash_hmac('sha256', $ciphertext_raw, $key, $as_binary=true);
if (hash_equals($hmac, $calcmac))//PHP 5.6+ timing attack safe comparison
{
    echo $original_plaintext."\n";
}
?>

Beispiel 3

Anhand der obigen Beispiele habe ich den folgenden Code geändert, mit dem die Sitzungs-ID des Benutzers verschlüsselt werden soll:

class Session {

  /**
   * Encrypts the session ID and returns it as a base 64 encoded string.
   *
   * @param $session_id
   * @return string
   */
  public function encrypt($session_id) {
    // Get the MD5 hash salt as a key.
    $key = $this->_getSalt();
    // For an easy iv, MD5 the salt again.
    $iv = $this->_getIv();
    // Encrypt the session ID.
    $encrypt = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $session_id, MCRYPT_MODE_CBC, $iv);
    // Base 64 encode the encrypted session ID.
    $encryptedSessionId = base64_encode($encrypt);
    // Return it.
    return $encryptedSessionId;
  }

  /**
   * Decrypts a base 64 encoded encrypted session ID back to its original form.
   *
   * @param $encryptedSessionId
   * @return string
   */
  public function decrypt($encryptedSessionId) {
    // Get the MD5 hash salt as a key.
    $key = $this->_getSalt();
    // For an easy iv, MD5 the salt again.
    $iv = $this->_getIv();
    // Decode the encrypted session ID from base 64.
    $decoded = base64_decode($encryptedSessionId);
    // Decrypt the string.
    $decryptedSessionId = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, $decoded, MCRYPT_MODE_CBC, $iv);
    // Trim the whitespace from the end.
    $session_id = rtrim($decryptedSessionId, "\0");
    // Return it.
    return $session_id;
  }

  public function _getIv() {
    return md5($this->_getSalt());
  }

  public function _getSalt() {
    return md5($this->drupal->drupalGetHashSalt());
  }

}

in:

class Session {

  const SESS_CIPHER = 'aes-128-cbc';

  /**
   * Encrypts the session ID and returns it as a base 64 encoded string.
   *
   * @param $session_id
   * @return string
   */
  public function encrypt($session_id) {
    // Get the MD5 hash salt as a key.
    $key = $this->_getSalt();
    // For an easy iv, MD5 the salt again.
    $iv = $this->_getIv();
    // Encrypt the session ID.
    $ciphertext = openssl_encrypt($session_id, self::SESS_CIPHER, $key, $options=OPENSSL_RAW_DATA, $iv);
    // Base 64 encode the encrypted session ID.
    $encryptedSessionId = base64_encode($ciphertext);
    // Return it.
    return $encryptedSessionId;
  }

  /**
   * Decrypts a base 64 encoded encrypted session ID back to its original form.
   *
   * @param $encryptedSessionId
   * @return string
   */
  public function decrypt($encryptedSessionId) {
    // Get the Drupal hash salt as a key.
    $key = $this->_getSalt();
    // Get the iv.
    $iv = $this->_getIv();
    // Decode the encrypted session ID from base 64.
    $decoded = base64_decode($encryptedSessionId, TRUE);
    // Decrypt the string.
    $decryptedSessionId = openssl_decrypt($decoded, self::SESS_CIPHER, $key, $options=OPENSSL_RAW_DATA, $iv);
    // Trim the whitespace from the end.
    $session_id = rtrim($decryptedSessionId, '\0');
    // Return it.
    return $session_id;
  }

  public function _getIv() {
    $ivlen = openssl_cipher_iv_length(self::SESS_CIPHER);
    return substr(md5($this->_getSalt()), 0, $ivlen);
  }

  public function _getSalt() {
    return $this->drupal->drupalGetHashSalt();
  }

}

Zur Verdeutlichung ist die obige Änderung keine echte Konvertierung, da die beiden Verschlüsselungen eine unterschiedliche Blockgröße und unterschiedliche verschlüsselte Daten verwenden. Darüber hinaus ist die Standardauffüllung unterschiedlich und MCRYPT_RIJNDAELunterstützt nur nicht standardmäßige Nullauffüllungen. @zaph


Zusätzliche Hinweise (aus den Kommentaren von @ zaph):

  • Rijndael 128 ( MCRYPT_RIJNDAEL_128) ist äquivalent zu AES , jedoch Rijndael 256 ( MCRYPT_RIJNDAEL_256) wird nicht AES-256 als 256 eine Blockgröße von 256-Bit gibt an , während AES nur eine Blockgröße hat: 128-Bit. Im Grunde genommen wurde Rijndael mit einer Blockgröße von 256 Bit ( MCRYPT_RIJNDAEL_256) aufgrund der Auswahl durch die mcrypt- Entwickler fälschlicherweise benannt . @zaph
  • Rijndael mit einer Blockgröße von 256 ist möglicherweise weniger sicher als mit einer Blockgröße von 128 Bit, da letztere viel mehr Überprüfungen und Verwendungen hatte. Zweitens wird die Interoperabilität dadurch behindert, dass AES allgemein verfügbar ist, Rijndael mit einer Blockgröße von 256 Bit jedoch nicht.
  • Die Verschlüsselung mit unterschiedlichen Blockgrößen für Rijndael erzeugt unterschiedliche verschlüsselte Daten.

    Beispielsweise definiert MCRYPT_RIJNDAEL_256(nicht äquivalent zu AES-256) eine andere Variante der Rijndael-Blockverschlüsselung mit einer Größe von 256 Bit und eine Schlüsselgröße basierend auf dem übergebenen Schlüssel, wobei aes-256-cbcRijndael eine Blockgröße von 128 Bit mit einer Schlüsselgröße von ist 256 Bit. Daher verwenden sie unterschiedliche Blockgrößen, wodurch völlig unterschiedliche verschlüsselte Daten erzeugt werden, da mcrypt die Nummer zur Angabe der Blockgröße verwendet, wobei OpenSSL die Nummer zur Angabe der Schlüsselgröße verwendet (AES hat nur eine Blockgröße von 128 Bit). AES ist also im Grunde Rijndael mit einer Blockgröße von 128 Bit und Schlüsselgrößen von 128, 192 und 256 Bit. Daher ist es besser, AES zu verwenden, das in OpenSSL Rijndael 128 heißt.

Kenorb
quelle
1
Im Allgemeinen ist die Verwendung von Rijndael mit einer Blockgröße von 256 Bit aufgrund der Auswahl durch die mcrypt-Entwickler ein Fehler. Weiterhin ist Rijndael mit einer Blockgröße von 256 möglicherweise weniger sicher als mit einer Blockgröße von 128 Bit, da letzterer viel mehr überprüft und verwendet wurde. Zusätzlich wird die Interoperabilität dadurch behindert, dass AES zwar allgemein verfügbar ist, Rijndael mit einer Blockgröße von 256 Bit jedoch nicht.
Zaph
Warum machst du $session_id = rtrim($decryptedSessionId, "\0");? Ist es möglich openssl_decrypt, am Ende einige unerwünschte Zeichen zurückzugeben? Was ist, wenn die verschlüsselte Variable mit 0 endet (dh encrypt("abc0")?
hlscalon
@hiscalon "\0"ist "0"nur das NULL-Zeichen, dessen ASCII-Code 0x00 (hexadezimal 0) ist.
Kiamlaluno
11

Die reine PHP-Implementierung von Rijndael existiert mit phpseclib als Composer-Paket und funktioniert unter PHP 7.3 (von mir getestet).

In den phpseclib-Dokumenten befindet sich eine Seite, auf der nach Eingabe der grundlegenden Variablen (Verschlüsselung, Modus, Schlüsselgröße, Bitgröße) Beispielcode generiert wird . Für Rijndael, EZB, 256, 256 wird Folgendes ausgegeben:

ein Code mit mycrypt

$decoded = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, ENCRYPT_KEY, $term, MCRYPT_MODE_ECB);

funktioniert so mit der Bibliothek

$rijndael = new \phpseclib\Crypt\Rijndael(\phpseclib\Crypt\Rijndael::MODE_ECB);
$rijndael->setKey(ENCRYPT_KEY);
$rijndael->setKeyLength(256);
$rijndael->disablePadding();
$rijndael->setBlockLength(256);

$decoded = $rijndael->decrypt($term);

* $termwarbase64_decoded

Pentium10
quelle
11

Wie in anderen Antworten hier beschrieben, ist die beste Lösung, die ich gefunden habe, die Verwendung von OpenSSL. Es ist in PHP integriert und Sie benötigen keine externe Bibliothek. Hier sind einfache Beispiele:

So verschlüsseln Sie:

function encrypt($key, $payload) {
  $iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length('aes-256-cbc'));
  $encrypted = openssl_encrypt($payload, 'aes-256-cbc', $key, 0, $iv);
  return base64_encode($encrypted . '::' . $iv);
}

So entschlüsseln Sie:

function decrypt($key, $garble) {
    list($encrypted_data, $iv) = explode('::', base64_decode($garble), 2);
    return openssl_decrypt($encrypted_data, 'aes-256-cbc', $key, 0, $iv);
}

Referenzlink: https://www.shift8web.ca/2017/04/how-to-encrypt-and-execute-your-php-code-with-mcrypt/

Ariston Cordeiro
quelle
Viel gutes Karma an deinen Freund! Nur eines: Wenn das Passwort beispielsweise mit dem alten Code verschlüsselt wurde, kann der neue Entschlüsselungscode es nicht verifizieren. Es muss erneut gespeichert und mit diesem neuen Code verschlüsselt werden.
Lumis
Ein einfaches Migrationsskript würde dieses Problem lösen. Verwenden Sie die alte Methode zum Entschlüsseln und dann die neue Methode zum Verschlüsseln und Speichern. Die Alternative besteht darin, der Benutzertabelle ein Flag hinzuzufügen und ein erzwungenes Zurücksetzen des Kennworts für alle Benutzerkonten vorzunehmen, für die Kennwortänderungen erforderlich sind.
Cecil Merrel aka Bringrainfire
8

Sie können das phpseclib pollyfill-Paket verwenden. Sie können open ssl oder libsodium nicht zum Ver- / Entschlüsseln mit rijndael 256 verwenden. Ein weiteres Problem: Sie müssen keinen Code ersetzen.

Ahmet Erkan ÇELİK
quelle
2
Das war super hilfreich, danke. Musste die Erweiterung php-mcrypt entfernen, und dann funktioniert das wie ein Zauber.
DannyB
Ich habe es mcrypt_compatdurch Laufen installiert , composer require phpseclib/mcrypt_compataber ich bekomme immer noch PHP Fatal error: Uncaught Error: Call to undefined function mcrypt_get_key_size() in /app/kohana/classes/Kohana/Encrypt.php:124PHP 7.2.26und Kohana Framwork. Müssen nach der Installation mit Composer weitere Schritte ausgeführt werden?
M-Dahab
Verstanden. Sie müssen require APPPATH . '/vendor/autoload.php';am Ende von hinzufügen bootstrap.php.
M-Dahab
3

Sie sollten OpenSSL verwenden, mcryptda es aktiv entwickelt und gewartet wird. Es bietet bessere Sicherheit, Wartbarkeit und Portabilität. Zweitens führt es die AES-Ver- / Entschlüsselung viel schneller durch. Standardmäßig wird PKCS7-Padding verwendet, Sie können jedoch angeben, OPENSSL_ZERO_PADDINGob Sie es benötigen. Zur Verwendung mit einem 32-Byte-Binärschlüssel können Sie angeben, aes-256-cbcwas viel offensichtlicher ist als MCRYPT_RIJNDAEL_128.

Hier ist das Codebeispiel mit Mcrypt:

Nicht authentifizierte AES-256-CBC-Verschlüsselungsbibliothek, geschrieben in Mcrypt mit PKCS7-Auffüllung.

/**
 * This library is unsafe because it does not MAC after encrypting
 */
class UnsafeMcryptAES
{
    const CIPHER = MCRYPT_RIJNDAEL_128;

    public static function encrypt($message, $key)
    {
        if (mb_strlen($key, '8bit') !== 32) {
            throw new Exception("Needs a 256-bit key!");
        }
        $ivsize = mcrypt_get_iv_size(self::CIPHER);
        $iv = mcrypt_create_iv($ivsize, MCRYPT_DEV_URANDOM);

        // Add PKCS7 Padding
        $block = mcrypt_get_block_size(self::CIPHER);
        $pad = $block - (mb_strlen($message, '8bit') % $block, '8bit');
        $message .= str_repeat(chr($pad), $pad);

        $ciphertext = mcrypt_encrypt(
            MCRYPT_RIJNDAEL_128,
            $key,
            $message,
            MCRYPT_MODE_CBC,
            $iv
        );

        return $iv . $ciphertext;
    }

    public static function decrypt($message, $key)
    {
        if (mb_strlen($key, '8bit') !== 32) {
            throw new Exception("Needs a 256-bit key!");
        }
        $ivsize = mcrypt_get_iv_size(self::CIPHER);
        $iv = mb_substr($message, 0, $ivsize, '8bit');
        $ciphertext = mb_substr($message, $ivsize, null, '8bit');

        $plaintext = mcrypt_decrypt(
            MCRYPT_RIJNDAEL_128,
            $key,
            $ciphertext,
            MCRYPT_MODE_CBC,
            $iv
        );

        $len = mb_strlen($plaintext, '8bit');
        $pad = ord($plaintext[$len - 1]);
        if ($pad <= 0 || $pad > $block) {
            // Padding error!
            return false;
        }
        return mb_substr($plaintext, 0, $len - $pad, '8bit');
    }
}

Und hier ist die mit OpenSSL geschriebene Version:

/**
 * This library is unsafe because it does not MAC after encrypting
 */
class UnsafeOpensslAES
{
    const METHOD = 'aes-256-cbc';

    public static function encrypt($message, $key)
    {
        if (mb_strlen($key, '8bit') !== 32) {
            throw new Exception("Needs a 256-bit key!");
        }
        $ivsize = openssl_cipher_iv_length(self::METHOD);
        $iv = openssl_random_pseudo_bytes($ivsize);

        $ciphertext = openssl_encrypt(
            $message,
            self::METHOD,
            $key,
            OPENSSL_RAW_DATA,
            $iv
        );

        return $iv . $ciphertext;
    }

    public static function decrypt($message, $key)
    {
        if (mb_strlen($key, '8bit') !== 32) {
            throw new Exception("Needs a 256-bit key!");
        }
        $ivsize = openssl_cipher_iv_length(self::METHOD);
        $iv = mb_substr($message, 0, $ivsize, '8bit');
        $ciphertext = mb_substr($message, $ivsize, null, '8bit');

        return openssl_decrypt(
            $ciphertext,
            self::METHOD,
            $key,
            OPENSSL_RAW_DATA,
            $iv
        );
    }
}

Quelle: Wenn Sie das Wort MCRYPT in Ihren PHP-Code eingeben, machen Sie es falsch .

Kenorb
quelle
2

Ich poste dies sehr spät, aber ich hoffe, es wird jemand anderem helfen, der das gleiche Problem in der PHP 7.2x-Version hat.

Ich benutze dies auf PHP 7.2x, es funktioniert gut für mich.

public function make_hash($userStr){
        try{
            /** 
             * Used and tested on PHP 7.2x, Salt has been removed manually, it is now added by PHP 
             */
             return password_hash($userStr, PASSWORD_BCRYPT);
            }catch(Exception $exc){
                $this->tempVar = $exc->getMessage();
                return false;
            }
        }

und authentifizieren Sie dann den Hash mit der folgenden Funktion:

public function varify_user($userStr,$hash){
        try{
            if (password_verify($userStr, $hash)) {
                 return true;
                }
            else {
                return false;
                }
            }catch(Exception $exc){
                $this->tempVar = $exc->getMessage();
                return false;
            }
        }

//Beispiel:

  //create hash from user string

 $user_password = $obj->make_hash2($user_key);

Verwenden Sie zur Authentifizierung dieses Hashs den folgenden Code:

if($obj->varify_user($key, $user_key)){
      //this is correct, you can proceed with  
    }

Das ist alles

Abdul Rahman
quelle
1

Wie bereits erwähnt, sollten Sie die Kennwörter Ihrer Benutzer nicht in einem entschlüsselbaren Format speichern. Die reversible Verschlüsselung bietet Hackern eine einfache Möglichkeit, die Kennwörter Ihrer Benutzer herauszufinden. Dies erstreckt sich auch darauf, die Konten Ihrer Benutzer an anderen Standorten zu gefährden, wenn sie dort dasselbe Kennwort verwenden.

PHP bietet zwei leistungsstarke Funktionen für die zufällige Einweg-Hash-Verschlüsselung - password_hash()und password_verify(). Da der Hash automatisch zufällig gesalzen wird, können Hacker keine vorkompilierten Tabellen mit Kennwort-Hashes verwenden, um das Kennwort zurückzuentwickeln. Stellen Sie die PASSWORD_DEFAULTOption ein und zukünftige Versionen von PHP verwenden automatisch stärkere Algorithmen, um Passwort-Hashes zu generieren, ohne dass Sie Ihren Code aktualisieren müssen.

Thoracius Appotite
quelle
1

Sie sollten die openssl_encrypt()Funktion verwenden.

rqLizard
quelle
Haben die openssl-Verschlüsselungen in PHP 7 das "Herzblut"?
TheCrazyProfessor
13
Warum sollte das OP openssl_encrypt verwenden? Geben Sie einige Details und Hintergrundinformationen
Martin
0

Ich konnte mein Crypto-Objekt übersetzen

  • Holen Sie sich eine Kopie von PHP mit mcrypt, um die alten Daten zu entschlüsseln. Ich ging zu http://php.net/get/php-7.1.12.tar.gz/from/a/mirror , kompilierte es und fügte dann die Erweiterung ext / mcrypt hinzu (configure; make; make install). Ich glaube, ich musste der Zeile php.ini auch die Zeile extenstion = mcrypt.so hinzufügen. Eine Reihe von Skripten zum Erstellen von Zwischenversionen der Daten, wobei alle Daten unverschlüsselt sind.

  • Erstellen Sie einen öffentlichen und einen privaten Schlüssel für openssl

    openssl genrsa -des3 -out pkey.pem 2048
    (set a password)
    openssl rsa -in pkey.pem -out pkey-pub.pem -outform PEM -pubout
  • Verwenden Sie zum Verschlüsseln (mit öffentlichem Schlüssel) openssl_seal. Nach dem, was ich gelesen habe, ist openssl_encrypt mit einem RSA-Schlüssel auf 11 Byte weniger als die Schlüssellänge begrenzt (siehe http://php.net/manual/en/function.openssl-public-encrypt.php Kommentar von Thomas Horsten).

    $pubKey = openssl_get_publickey(file_get_contents('./pkey-pub.pem'));
    openssl_seal($pwd, $sealed, $ekeys, [ $pubKey ]);
    $encryptedPassword = base64_encode($sealed);
    $key = base64_encode($ekeys[0]);

Sie könnten wahrscheinlich die rohe Binärdatei speichern.

  • Entschlüsseln (mit privatem Schlüssel)

    $passphrase="passphrase here";
    $privKey = openssl_get_privatekey(file_get_contents('./pkey.pem'), $passphrase);
    // I base64_decode() from my db columns
    openssl_open($encryptedPassword, $plain, $key, $privKey);
    echo "<h3>Password=$plain</h3>";

PS Sie können die leere Zeichenfolge ("") nicht verschlüsseln.

PPS Dies ist für eine Kennwortdatenbank, die nicht zur Benutzerüberprüfung dient.

Joshua Goldstein
quelle