双方向暗号化:取得できるパスワードを保存する必要がある


174

ユーザーを取得して表示できるパスワードを保存するアプリケーションを作成しています。パスワードはハードウェアデバイス用なので、ハッシュをチェックすることは問題外です。

私が知る必要があるのは:

  1. PHPでパスワードを暗号化および復号化するにはどうすればよいですか?

  2. パスワードを暗号化する最も安全なアルゴリズムは何ですか?

  3. 秘密鍵はどこに保存しますか?

  4. 秘密鍵を保存する代わりに、パスワードを復号化する必要があるときはいつでもユーザーに秘密鍵の入力を要求するのは良い考えですか?(このアプリケーションのユーザーは信頼できます)

  5. パスワードはどのように盗まれ、解読されますか?何に注意する必要がありますか?


1
注:Libsodiumは、7.2以降のPHPコアにコンパイルされています。これは、非推奨と見なされて削除されたmcryptとは異なり、最新のメソッドでいっぱいなので、「進む」ソリューションになります。
出展者

回答:


212

個人的には、mcrypt他の人が投稿したように使用します。しかし、注意すべきことは他にもたくさんあります...

  1. PHPでパスワードを暗号化および復号化するにはどうすればよいですか?

    すべてを処理する強力なクラスについては、以下を参照してください。

  2. パスワードを暗号化する最も安全なアルゴリズムは何ですか?

    最も安全ですか?それらのいずれか。暗号化する場合の最も安全な方法は、情報漏えいの脆弱性(XSS、リモートインクルードなど)から保護することです。暗号化が解除された場合、攻撃者は最終的に暗号化を解読できます(暗号化は鍵なしでは100%元に戻せません-@NullUserExceptionが指摘しているように、これは完全に真実ではありません。OneTimePadなど、解読できない暗号化スキームがいくつかあります) 。

  3. 秘密鍵はどこに保存しますか?

    3つのキーを使用します。1つはユーザー指定、1つはアプリケーション固有、もう1つはユーザー固有(ソルトなど)です。アプリケーション固有のキーはどこにでも保存できます(web-rootの外部の設定ファイル、環境変数など)。ユーザー固有のものは、暗号化されたパスワードの隣のdbの列に格納されます。ユーザーが提供したものは保存されません。次に、次のようなことを行います。

    $key = $userKey . $serverKey . $userSuppliedKey;

    そこでの利点は、データが危険にさらされることなく、任意の2つのキーが危険にさらされる可能性があることです。SQLインジェクション攻撃があれば、彼らが得ることができる$userKey、ではなく、他の2ローカルサーバーが不正利用がある場合、彼らが得ることができる$userKey$serverKey、しかし第三ません$userSuppliedKey。ユーザーがレンチでユーザーを倒した場合、彼らはを取得できます$userSuppliedKeyが、他の2つは取得できません(ただし、ユーザーがレンチで倒された場合は、とにかく遅すぎます)。

  4. 秘密鍵を保存する代わりに、パスワードを復号化する必要があるときはいつでもユーザーに秘密鍵の入力を要求するのは良い考えですか?(このアプリケーションのユーザーは信頼できます)

    もちろんです。実際、それが私が行う唯一の方法です。それ以外の場合は、暗号化されていないバージョンを永続的なストレージ形式(APCやmemcachedなどの共有メモリ、またはセッションファイル)に保存する必要があります。これは、さらなる妥協にさらされています。暗号化されていないバージョンのパスワードは、ローカル変数以外には決して保存しないでください。

  5. パスワードはどのように盗まれ、解読されますか?何に注意する必要がありますか?

    システムが侵害されると、暗号化されたデータが表示されます。コードを挿入したり、ファイルシステムにアクセスしたりできる場合は、復号化されたデータを表示できます(データを復号化するファイルを編集できるため)。あらゆる形態のリプレイまたはMITM攻撃でも、関係するキーへの完全なアクセス権が与えられます。生のHTTPトラフィックをスニッフィングすると、キーも提供されます。

    すべてのトラフィックにSSLを使用します。また、サーバーに何の種類の脆弱性(CSRF、XSS、SQLインジェクション、特権エスカレーション、リモートコード実行など)がないことを確認してください。

編集:強力な暗号化メソッドのPHPクラス実装は次のとおりです。

/**
 * A class to handle secure encryption and decryption of arbitrary data
 *
 * Note that this is not just straight encryption.  It also has a few other
 *  features in it to make the encrypted data far more secure.  Note that any
 *  other implementations used to decrypt data will have to do the same exact
 *  operations.  
 *
 * Security Benefits:
 *
 * - Uses Key stretching
 * - Hides the Initialization Vector
 * - Does HMAC verification of source data
 *
 */
class Encryption {

    /**
     * @var string $cipher The mcrypt cipher to use for this instance
     */
    protected $cipher = '';

    /**
     * @var int $mode The mcrypt cipher mode to use
     */
    protected $mode = '';

    /**
     * @var int $rounds The number of rounds to feed into PBKDF2 for key generation
     */
    protected $rounds = 100;

    /**
     * Constructor!
     *
     * @param string $cipher The MCRYPT_* cypher to use for this instance
     * @param int    $mode   The MCRYPT_MODE_* mode to use for this instance
     * @param int    $rounds The number of PBKDF2 rounds to do on the key
     */
    public function __construct($cipher, $mode, $rounds = 100) {
        $this->cipher = $cipher;
        $this->mode = $mode;
        $this->rounds = (int) $rounds;
    }

    /**
     * Decrypt the data with the provided key
     *
     * @param string $data The encrypted datat to decrypt
     * @param string $key  The key to use for decryption
     * 
     * @returns string|false The returned string if decryption is successful
     *                           false if it is not
     */
    public function decrypt($data, $key) {
        $salt = substr($data, 0, 128);
        $enc = substr($data, 128, -64);
        $mac = substr($data, -64);

        list ($cipherKey, $macKey, $iv) = $this->getKeys($salt, $key);

        if (!hash_equals(hash_hmac('sha512', $enc, $macKey, true), $mac)) {
             return false;
        }

        $dec = mcrypt_decrypt($this->cipher, $cipherKey, $enc, $this->mode, $iv);

        $data = $this->unpad($dec);

        return $data;
    }

    /**
     * Encrypt the supplied data using the supplied key
     * 
     * @param string $data The data to encrypt
     * @param string $key  The key to encrypt with
     *
     * @returns string The encrypted data
     */
    public function encrypt($data, $key) {
        $salt = mcrypt_create_iv(128, MCRYPT_DEV_URANDOM);
        list ($cipherKey, $macKey, $iv) = $this->getKeys($salt, $key);

        $data = $this->pad($data);

        $enc = mcrypt_encrypt($this->cipher, $cipherKey, $data, $this->mode, $iv);

        $mac = hash_hmac('sha512', $enc, $macKey, true);
        return $salt . $enc . $mac;
    }

    /**
     * Generates a set of keys given a random salt and a master key
     *
     * @param string $salt A random string to change the keys each encryption
     * @param string $key  The supplied key to encrypt with
     *
     * @returns array An array of keys (a cipher key, a mac key, and a IV)
     */
    protected function getKeys($salt, $key) {
        $ivSize = mcrypt_get_iv_size($this->cipher, $this->mode);
        $keySize = mcrypt_get_key_size($this->cipher, $this->mode);
        $length = 2 * $keySize + $ivSize;

        $key = $this->pbkdf2('sha512', $key, $salt, $this->rounds, $length);

        $cipherKey = substr($key, 0, $keySize);
        $macKey = substr($key, $keySize, $keySize);
        $iv = substr($key, 2 * $keySize);
        return array($cipherKey, $macKey, $iv);
    }

    /**
     * Stretch the key using the PBKDF2 algorithm
     *
     * @see http://en.wikipedia.org/wiki/PBKDF2
     *
     * @param string $algo   The algorithm to use
     * @param string $key    The key to stretch
     * @param string $salt   A random salt
     * @param int    $rounds The number of rounds to derive
     * @param int    $length The length of the output key
     *
     * @returns string The derived key.
     */
    protected function pbkdf2($algo, $key, $salt, $rounds, $length) {
        $size   = strlen(hash($algo, '', true));
        $len    = ceil($length / $size);
        $result = '';
        for ($i = 1; $i <= $len; $i++) {
            $tmp = hash_hmac($algo, $salt . pack('N', $i), $key, true);
            $res = $tmp;
            for ($j = 1; $j < $rounds; $j++) {
                 $tmp  = hash_hmac($algo, $tmp, $key, true);
                 $res ^= $tmp;
            }
            $result .= $res;
        }
        return substr($result, 0, $length);
    }

    protected function pad($data) {
        $length = mcrypt_get_block_size($this->cipher, $this->mode);
        $padAmount = $length - strlen($data) % $length;
        if ($padAmount == 0) {
            $padAmount = $length;
        }
        return $data . str_repeat(chr($padAmount), $padAmount);
    }

    protected function unpad($data) {
        $length = mcrypt_get_block_size($this->cipher, $this->mode);
        $last = ord($data[strlen($data) - 1]);
        if ($last > $length) return false;
        if (substr($data, -1 * $last) !== str_repeat(chr($last), $last)) {
            return false;
        }
        return substr($data, 0, -1 * $last);
    }
}

PHP 5.6で追加された関数を使用していることに注意してくださいhash_equals。5.6未満の場合は、二重HMAC検証を使用してタイミングセーフな比較関数を実装するこの代替関数を使用できます。

function hash_equals($a, $b) {
    $key = mcrypt_create_iv(128, MCRYPT_DEV_URANDOM);
    return hash_hmac('sha512', $a, $key) === hash_hmac('sha512', $b, $key);
}

使用法:

$e = new Encryption(MCRYPT_BLOWFISH, MCRYPT_MODE_CBC);
$encryptedData = $e->encrypt($data, $key);

次に、復号化するには:

$e2 = new Encryption(MCRYPT_BLOWFISH, MCRYPT_MODE_CBC);
$data = $e2->decrypt($encryptedData, $key);

$e22回目は別のインスタンスがデータを適切に復号化することを示すために使用したことに注意してください。

今、それはどのように機能しますか/別のソリューションでそれを使用する理由:

  1. キー

    • キーは直接使用されません。代わりに、キーは標準のPBKDF2派生によって拡張されます。

    • 暗号化に使用されるキーは、暗号化されたテキストブロックごとに一意です。したがって、提供された鍵は「マスター鍵」になります。したがって、このクラスは、暗号キーと認証キーのキーローテーションを提供します。

    • 重要な注意事項:この$roundsパラメーターは、十分な強度を持つ真のランダムキー(最低でも128ビットの暗号で保護されたランダム)に対して構成されます。パスワードまたは非ランダムキー(またはランダムではなく128ビットのCSランダム)を使用する場合、このパラメーターを増やす必要があります。パスワードには最低10000をお勧めします(余裕があるほど良いですが、ランタイムに追加されます)...

  2. データの整合性

    • 更新されたバージョンではENCRYPT-THEN-MACを使用しています。これは、暗号化されたデータの信頼性を保証するためのはるかに優れた方法です。
  3. 暗号化:

    • mcryptを使用して実際に暗号化を実行します。MCRYPT_BLOWFISHまたはMCRYPT_RIJNDAEL_128cyphersのいずれかを使用MCRYPT_MODE_CBCし、モードに使用することをお勧めします。十分に強力であり、それでもかなり高速です(私のマシンでは、暗号化と復号化のサイクルに約1/2秒かかります)。

さて、最初のリストのポイント3に関しては、次のような関数が得られます。

function makeKey($userKey, $serverKey, $userSuppliedKey) {
    $key = hash_hmac('sha512', $userKey, $serverKey);
    $key = hash_hmac('sha512', $key, $userSuppliedKey);
    return $key;
}

あなたはそれを伸ばすことができmakeKey()機能が、それは、後に引き伸ばされるために起こっているので、そうすることへの大きなポイントは、実際にそこではありません。

保存サイズに関しては、プレーンテキストに依存します。Blowfishは8バイトのブロックサイズを使用するため、次のようになります。

  • ソルト用に16バイト
  • hmac用に64バイト
  • データ長
  • データ長%8 == 0になるようにパディング

したがって、16文字のデータソースの場合、暗号化されるデータは16文字になります。つまり、パディングにより、実際の暗号化データサイズは16バイトになります。次に、saltに16バイト、hmacに64バイトを追加すると、格納される合計サイズは96バイトになります。だから、せいぜい80文字のオーバーヘッドがあり、最悪でも87文字のオーバーヘッドがあります...

それが役に立てば幸い...

注: 12/11/12:このクラスを更新して、はるかに優れた暗号化方法、より適切な派生キーを使用し、MAC生成を修正しました...


3
誰かがそれが「休憩」の意味を理解していません。@IRCはクラスで素晴らしい仕事でした。それはかなりのろわれた素晴らしいコードです。
jcolebrand

1
次はfalseを返します。なぜだと思いますか?$ x =新しい暗号化(MCRYPT_BlOWFISH、MCRYPT_MODE_CBC); $ test = $ x-> encrypt( "test"、 "a"); echo var_dump($ x-> decrypt($ test、 "a"));
波長

2
ああして再度復号化機能に2つの変更-64にSを-128助けた(あなたが得るように、$enc = substr($data, 128, -128)$mac = substr($data, -128);
cosmorogers

4
@ircmaxellコードが最後に改訂されてからかなり経ちましたので、それが最新かどうか疑問に思っています。私は金融アプリケーションに同様の何かを使用する必要があります。このクラスで大丈夫だとしたらいいでしょう:-)
nt.bas

2
警告!mcrypt拡張機能は10年近く前から放棄されており、使用するのもかなり複雑でした。そのため、OpenSSLの代わりに非推奨になり、PHP 7.2でコアからPECLに削除されます。 th1.php.net/manual/en/migration71.deprecated.php
VEE

15

PHPでパスワードを暗号化および復号化するにはどうすればよいですか? 多くの暗号化アルゴリズムの1つを実装する。(または多くのライブラリのいずれかを使用)

パスワードを暗号化する最も安全なアルゴリズムは何ですか? さまざまなアルゴリズムがたくさんありますが、どれも100%安全ではありません。しかし、それらの多くは商取引や軍事目的でさえ十分に安全です

秘密鍵はどこに保存しますか? 公開鍵-暗号化アルゴリズム(RSAなど)を実装することにした場合は、秘密鍵を保存しません。ユーザーは秘密鍵を持っています。あなたのシステムはあなたが望むどこにでも保存できる公開鍵を持っています。

秘密鍵を保存する代わりに、パスワードを復号化する必要があるときはいつでもユーザーに秘密鍵の入力を要求するのは良い考えですか?(このアプリケーションのユーザーは信頼できます) さて、もしあなたのユーザーが途方もなく長い素数を覚えているなら、そうです-はい、なぜでしょうか。しかし、一般的には、ユーザーが自分の鍵をどこかに保存できるようにするシステムを考え出す必要があります。

パスワードはどのように盗まれ、解読されますか?何に注意する必要がありますか? これは、使用するアルゴリズムによって異なります。ただし、暗号化されていないパスワードをユーザーに送信したり、ユーザーから送信したりしないでください。クライアント側で暗号化/復号化するか、https(またはユーザーと他の暗号化手段を使用してサーバーとクライアント間の接続を保護します)。

ただし、暗号化された方法でパスワードを保存することだけが必要な場合は、単純なXOR暗号を使用することをお勧めします。このアルゴリズムの主な問題は、周波数分析によって簡単に破られる可能性があることです。しかし、一般的にパスワードは英語のテキストの長い段落から作られているわけではないので、心配する必要はないと思います。XOR暗号の2番目の問題は、暗号化された形式と復号化された形式の両方のメッセージがある場合、メッセージが暗号化されたパスワードを簡単に見つけられることです。繰り返しますが、あなたのケースでは大きな問題ではありません。他の手段によってすでに侵害されたユーザーにのみ影響を与えるからです。


回答3で、ユーザーが秘密鍵を持っていると言ったとき、それが何を意味するのか理解できません。ユーザーが手動で秘密鍵をアプリケーションに渡すことはお勧めしません。そのため、秘密鍵を他にどのようにアプリケーションに渡すのでしょうか。
HyderA

まあそれは少し問題です。秘密鍵をテキストファイルに保存し、アプリにコピーして貼り付けることができます。キーはサーバーに保存することもできますが、この場合でも、XORなどの他の暗号化アルゴリズムで暗号化する必要があります。この場合のXORの使用は、パスワードとメッセージのペアが1つしかなく、メッセージが非常にランダムであるため、周波数分析を使用しないため、十分に安全です。
イヴァン

4
暗号化アルゴリズムを自分で実装することはお勧めしません。潜在的な落とし穴が多すぎて、既存のライブラリは多くの人々によってテストおよび分析されています。
ロングイヤー

XORの主な問題は、誰かがアプリケーションデータを盗んでユーザーのパスワードの1つだけを知っている場合、そのユーザーの他のすべてのパスワードを解読できることです。
Long Ears、2011

1
@Ivan:はい、でも、暗号を本当に理解しない限り、DIYが本当に悪いと思うケースの1つです。強力な暗号が存在しますが、それらを使用してみませんか?
ircmaxell

13
  1. あなたが追いかけているPHP関数はMcrypt(http://www.php.net/manual/en/intro.mcrypt.php)です。

マニュアルの例はこの例のために少し編集されています):

<?php
$iv_size = mcrypt_get_iv_size(MCRYPT_BLOWFISH, MCRYPT_MODE_ECB);
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
$key = "This is a very secret key";
$pass = "PasswordHere";
echo strlen($pass) . "\n";

$crypttext = mcrypt_encrypt(MCRYPT_BLOWFISH, $key, $pass, MCRYPT_MODE_ECB, $iv);
echo strlen($crypttext) . "\n";
?>

mcrypt_decryptを使用してパスワードを復号化します。

  1. 最良のアルゴリズムはかなり主観的です-5人に質問し、5つの回答を取得してください。個人的には、デフォルト(Blowfish)では十分ではない場合、おそらくさらに大きな問題が発生します!

  2. PHPが暗号化する必要があることを考えると-どこにでも隠すことができるかどうかわからない-これに関するコメントを歓迎します。もちろん、PHPの標準的なコーディングのベストプラクティスが適用されます。

  3. とにかく暗号化キーがコードに含まれているとすると、アプリケーションの残りの部分が安全であれば、何が得られるかはわかりません。

  4. 明らかに、暗号化されたパスワードと暗号化キーが盗まれた場合は、ゲームオーバーです。

私は自分の答えにライダーを入れます-私はPHP暗号化の専門家ではありませんが、私が答えたのは標準的な慣習だと思います-他の人のコメントを歓迎します。


$pass = $text。私は彼が質問に応えるためにそれを変えたと思います、そして2番目の発生に気づきませんでした。
HyderA、2011

3
注意すべき2つの点。まず、MCRYPT_MODE_ECBIVを使用しません。第二に、それがなければデータを復号化できないのでIVを保存する必要があります...
ircmaxell

「最良のアルゴリズムはどちらかといえば主観的です。5人に聞いて5つの答えを得てください。個人的には、デフォルト(Blowfish)が十分ではない場合、おそらくより大きな問題が発生します!」これは完全に間違っています。暗号の専門家は、多かれ少なかれ、特にフグを除外するgist.github.com/tqbf/be58d2d39690c3b366adに同意します
Scott Arciszewski

6

多くのユーザーがmcryptの使用を提案しています...これは正しいですが、簡単に保存して転送できるようにさらに一歩進めたいと思います(暗号化された値は、curlやjsonなどの他のテクノロジーを使用して送信するのを難しくすることがあります) 。

mcryptを使用して正常に暗号化した後、base64_encodeで実行してから、16進コードに変換します。16進コードになると、さまざまな方法で簡単に転送できます。

$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));

そして反対側では:

$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);


2
まあ-それは2011年でした:P
ブラッドリー

5

対話なしでユーザーのパスワードを設定する機能が必要な場合にのみ公開鍵暗号化をお勧めします(これはリセットや共有パスワードに便利です)。

公開鍵

  1. OpenSSL特に拡張、openssl_public_encryptおよびopenssl_private_decrypt
  2. これは、パスワードがキーサイズに収まると仮定した場合の直接のRSAです-パディング、それ以外の場合は対称レイヤーが必要です
  3. 各ユーザーの両方のキーを格納します。秘密キーのパスフレーズは、アプリケーションのパスワードです

対称

  1. Mcrypt拡張
  2. AES-256はおそらく安全な賭けですが、これはそれ自体がSOの質問になる可能性があります
  3. しない-これはアプリケーションのパスワードになります

両方とも

4。はい-ユーザーは毎回アプリケーションパスワードを入力する必要がありますが、セッションに保存すると他の問題が発生します

5

  • 誰かがアプリケーションデータを盗んだ場合、それは対称暗号と同じくらい安全です(公開鍵スキームの場合、これはパスフレーズで秘密鍵を保護するために使用されます)。
  • アプリケーションは確実にSSL経由でのみアクセス可能である必要があり、できればクライアント証明書を使用する必要があります。
  • SMS経由で送信されるトークンのように、セッションごとに1回だけ使用される認証の2番目の要素を追加することを検討してください。

mcryptを避け、に注意してくださいopenssl_private_decrypt()
Scott Arciszewski、2016

2

私はこのようなことを試しましたが、私は暗号学者ではなく、phpまたはプログラミング言語に関する深い知識を持っていないことに注意してください。それは単なるアイデアです。私のアイデアは、簡単に予測できないkeyファイルdatabase(または手動で入力)に保存することです(もちろん、いつかは復号化されますが、その概念は復号化時間を長くすることです)、機密情報を暗号化することです。

$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.

あくまでもコンセプトです。このコードの改善は非常に高く評価されます。


2

パスワードはハードウェアデバイス用であるため、ハッシュをチェックすることは問題外です

え?わかりません。パスワードが回復可能でなければならないということですか?

他の人が言ったように、mcrypt拡張機能は多くの暗号化機能へのアクセスを提供します-ただし、すべての卵を1つのバスケットに入れるようにユーザーを招待します-潜在的に攻撃者の標的になる可能性がある-そしてあなたが知らない場合でもどのように問題の解決を開始したら、ユーザーに害を及ぼします。データを保護する方法を理解する立場にありません。

ほとんどのセキュリティの脆弱性は、根本的なアルゴリズムに欠陥があるか安全でないためではなく、アプリケーションコード内でのアルゴリズムの使用方法に関する問題が原因です。

そうは言っても、かなり安全なシステムを構築することは可能です。

ユーザーが別の(特定の)ユーザーが読み取ることができる安全なメッセージを作成する必要がある場合にのみ、非対称暗号化を検討する必要があります。その理由は、その計算コストが高いことです。ユーザーが自分のデータを入力および取得するためのリポジトリを提供するだけの場合は、対称暗号化で十分です。

ただし、メッセージを復号化するためのキーを暗号化されたメッセージと同じ場所(または暗号化されたメッセージが保存されている場所)に保存する場合、システムは安全ではありません。ユーザーの認証には、復号化キーと同じトークンを使用します(または、非対称暗号化の場合は、トークンを秘密キーのパスフレーズとして使用します)。少なくとも一時的に復号化が行われるサーバーにトークンを保存する必要があるため、検索不可能なセッションストレージサブストレートを使用するか、またはトークンを保存するセッションに関連付けられているデーモンに直接トークンを渡すことを検討してください。トークンをメモリに格納し、要求に応じてメッセージの復号化を実行します。


1

password_hashpassword_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";
?>

そして復号化するには:

<?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.';
}
?>
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.