[php] Zwei-Wege-Verschlüsselung: Ich muss Passwörter speichern, die abgerufen werden können


3 Answers

Wie kann ich ein Passwort in PHP verschlüsseln und entschlüsseln? Durch die Implementierung eines von vielen Verschlüsselungsalgorithmen. (oder mit einer von vielen Bibliotheken)

Was ist der sicherste Algorithmus zum Verschlüsseln der Passwörter? Es gibt Tonnen von verschiedenen Algorithmen, von denen keiner 100% sicher ist. Aber viele von ihnen sind sicher genug für Handel und sogar militärische Zwecke

Wo kann ich den privaten Schlüssel speichern? Wenn Sie sich entschieden haben, einen öffentlichen Schlüssel - Kryptografiealgorithmus (z. B. RSA) zu implementieren, speichern Sie keinen privaten Schlüssel. Benutzer haben einen privaten Schlüssel. Ihr System verfügt über einen öffentlichen Schlüssel, der beliebig gespeichert werden kann.

Anstatt den privaten Schlüssel zu speichern, ist es eine gute Idee, dass Benutzer den privaten Schlüssel jedes Mal eingeben müssen, wenn sie ein entschlüsseltes Passwort benötigen? (Benutzern dieser Anwendung kann vertraut werden) Nun, wenn Ihr Benutzer sich an lächerlich lange Primzahlen erinnern kann, dann - ja, warum nicht. Aber im Allgemeinen müssen Sie das System entwickeln, das es dem Benutzer ermöglicht, seinen Schlüssel irgendwo zu speichern.

Wie kann das Passwort gestohlen und entschlüsselt werden? Worauf muss ich achten? Dies hängt vom verwendeten Algorithmus ab. Stellen Sie jedoch immer sicher, dass Sie das Passwort nicht unverschlüsselt an den oder vom Benutzer senden. Entweder verschlüsseln / entschlüsseln Sie es auf der Client-Seite, oder verwenden Sie https (oder andere kryptografische Mittel des Benutzers, um die Verbindung zwischen Server und Client zu sichern).

Wenn Sie jedoch lediglich Kennwörter verschlüsselt speichern müssen, würde ich Ihnen einen einfachen XOR-Chiffrierschlüssel empfehlen. Das Hauptproblem dieses Algorithmus besteht darin, dass er leicht durch Frequenzanalyse gebrochen werden kann. Da jedoch im Allgemeinen keine Passwörter aus langen Absätzen von englischem Text bestehen, denke ich nicht, dass Sie sich darüber Gedanken machen sollten. Das zweite Problem mit XOR Cipher besteht darin, dass Sie, wenn Sie eine Nachricht in verschlüsselter und entschlüsselter Form haben, leicht herausfinden können, mit welchem ​​Passwort sie verschlüsselt wurde. Auch dies ist in Ihrem Fall kein großes Problem, da es nur den Benutzer betrifft, der bereits auf andere Weise kompromittiert wurde.

Question

Ich erstelle eine Anwendung, die Passwörter speichert, die der Benutzer abrufen und sehen kann. Die Passwörter sind für ein Hardwaregerät, so dass eine Überprüfung gegen Hashes nicht in Frage kommt.

Was ich wissen muss ist:

  1. Wie kann ich ein Passwort in PHP verschlüsseln und entschlüsseln?

  2. Was ist der sicherste Algorithmus zum Verschlüsseln der Passwörter?

  3. Wo kann ich den privaten Schlüssel speichern?

  4. Anstatt den privaten Schlüssel zu speichern, ist es eine gute Idee, dass Benutzer den privaten Schlüssel jedes Mal eingeben müssen, wenn sie ein entschlüsseltes Passwort benötigen? (Benutzern dieser Anwendung kann vertraut werden)

  5. Wie kann das Passwort gestohlen und entschlüsselt werden? Worauf muss ich achten?




Ich habe so etwas probiert, aber bitte beachte, dass ich weder Kryptograf bin, noch php Kenntnisse über php oder irgendeine php Programmiersprache habe. Es ist nur eine Idee. Meine Idee ist es, key in einer Datei oder database zu speichern (oder manuell eingeben), die (Lage) nicht leicht vorhergesagt werden kann (und natürlich wird alles irgendwann entschlüsselt werden, das Konzept ist die Entschlüsselungszeit zu verlängern) und vertrauliche Informationen verschlüsseln.

$iv_size = mcrypt_get_iv_size(MCRYPT_BLOWFISH , MCRYPT_MODE_ECB);
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
$key = "evenifyouaccessmydatabaseyouwillneverfindmyemail";
$text = "myemail@domain.com";
echo "Key : ".$key."<br/>";
echo "Text : ".$text . "<br/>";
echo "Md5 : ".md5($text). "<br/>";
echo "Sha1 : ".sha1($text). "<br/>";



$crypttext = mcrypt_encrypt(MCRYPT_BLOWFISH , $key, $text, MCRYPT_MODE_ECB, $iv);
echo "Crypted Data : ".$crypttext."<br>";

$base64 = base64_encode($crypttext);
echo "Encoded Data : ".$base64."<br/>";
$decode =  base64_decode($base64);


$decryptdata = mcrypt_decrypt(MCRYPT_BLOWFISH , $key, $crypttext, MCRYPT_MODE_ECB, $iv);

echo "Decoded Data : ".ereg_replace("?", null ,  $decryptdata); 
//event if i add '?' to the sting to the text it works, I don't know why.

Bitte beachten Sie, dass es sich nur um ein Konzept handelt. Jede Verbesserung dieses Codes wäre sehr bemerkenswert.




Verwenden Sie password_hash und password_verify

<?php
/**
 * In this case, we want to increase the default cost for BCRYPT to 12.
 * Note that we also switched to BCRYPT, which will always be 60 characters.
 */
$options = [
    'cost' => 12,
];
echo password_hash("rasmuslerdorf", PASSWORD_BCRYPT, $options)."\n";
?>

Und um zu entschlüsseln:

<?php
// See the password_hash() example to see where this came from.
$hash = '$2y$07$BCryptRequires22Chrcte/VlQH0piJtjXl.0t1XkA8pw9dMXTpOq';

if (password_verify('rasmuslerdorf', $hash)) {
    echo 'Password is valid!';
} else {
    echo 'Invalid password.';
}
?>



Viele Benutzer haben vorgeschlagen, mcrypt zu verwenden ... was richtig ist, aber ich gehe gerne einen Schritt weiter, um es leicht zu speichern und zu übertragen (da manchmal verschlüsselte Werte es schwierig machen, sie mit anderen Technologien wie curl oder json zu senden) .

Nachdem Sie erfolgreich mit mcrypt verschlüsselt haben, führen Sie es über base64_encode aus und wandeln es anschließend in Hexcode um. Einmal im Hex-Code ist es einfach, auf verschiedene Arten zu übertragen.

$td = mcrypt_module_open('tripledes', '', 'ecb', '');
$iv = mcrypt_create_iv (mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
$key = substr("SUPERSECRETKEY",0,mcrypt_enc_get_key_size($td));
mcrypt_generic_init($td, $key, $iv);
$encrypted = mcrypt_generic($td, $unencrypted);
$encrypted = $ua."||||".$iv;
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
$encrypted = base64_encode($encrypted);
$encrypted = array_shift(unpack('H*', $encrypted));

Und auf der anderen Seite:

$encrypted = pack('H*', $encrypted);
$encrypted = base64_decode($encrypted);
list($encrypted,$iv) = explode("||||",$encrypted,2);
$td = mcrypt_module_open('tripledes', '', 'ecb', '');
$key = substr("SUPERSECRETKEY",0,mcrypt_enc_get_key_size($td));
mcrypt_generic_init($td, $key, $iv);
$unencrypted = mdecrypt_generic($td, $encrypted);
mcrypt_generic_deinit($td);
mcrypt_module_close($td);



Related