4

Web アプリケーションのユーザーに、smtp サーバーを使用して電子メールを送信できるようにしたいと考えています。

ユーザー アカウントのパスワードは md5-hased であり、smtp サーバーは受信した値をハッシュして、正しいユーザー名とパスワードの組み合わせを確認します。

今、私は Zend_Mail_Transport_Smtp を設定する良い方法を探しています - 私は明らかに平文のパスワードを必要とし、それを smtp-server に転送し、それを md5-hash に変換します。しかし、それは、ユーザーのパスワードをプレーンテキストでどこかに保存する必要があることを意味します。これは避けたいと思います。

Zend フレームワークを使用して Web メーラーをセットアップする方法に関するベスト プラクティスはありますか?

私が持っていた唯一のアイデアは、ハッシュされていないパスワードをセッションに保存することでした (私のアプリケーションのユーザー アカウントはメール サーバー アカウントにリンクされています) が、この状況を処理するためのより良い方法が必要です。

4

1 に答える 1

3

できることは、パスワードをエンコードされた形式でデータベースに保存し、必要なときにアプリケーションでデコードすることです。残念ながら、 MD5は単なるハッシュ関数であり、プレーン パスワードにデコードすることはできません。これを達成するための 3 つの方法を知っています。

  1. 代替文字:

    ROT13のようなものを使用して、単純なパスワードの文字を置き換えることができます。

    // store this in the database
    $pw_rot = str_rot13( "plain_password" );
    // use this in the application
    $pw_plain = str_rot13( "cynva_cnffjbeq" );
    

    str_rot13()パスワードを見た人が簡単に推測できるため、このようなものを使用することはお勧めしません。

  2. キーなしでデコード/エンコード:

    別の方法は、 Base64のようなキーを必要としない関数でパスワードをデコード/エンコードすることです:

    // store this in the database
    $pw_base64 = base64_encode( "plain_password" );
    // use this in the application
    $pw_plain = base64_encode( "cGxhaW5fcGFzc3dvcmQ=" );
    

    上記よりも少し優れていますが、簡単に実装して使用できるため、テスト目的でのみ使用します。

  3. キーを使用してデコード/エンコードします。

    より良い方法は、キーとBlowfishのような対称ブロック暗号を使用することです:

    class Password {
      const KEY = 'your_secret_key_for_the_cipher';
    
      // encode the plain text with key for storing in the database
      public function encode( $plain_text ) {
        // set up the environment
        $td      = mcrypt_module_open( MCRYPT_BLOWFISH, '', MCRYPT_MODE_ECB, '' );
        $key     = substr( self::KEY, 0, mcrypt_enc_get_key_size( $td ) );
        $iv_size = mcrypt_enc_get_iv_size( $td );
        $iv      = mcrypt_create_iv( $iv_size, MCRYPT_RAND );
    
        if( mcrypt_generic_init( $td, $key, $iv ) != -1 ) {
          $cipher_text = mcrypt_generic( $td, $plain_text );
          // clean up the mcrypt enviroment
          mcrypt_generic_deinit( $td );
          mcrypt_module_close( $td );
        }
    
        // use hex value            
        return bin2hex( $cipher_text );
      }
    
      // decode the stored cipher text with key to use in the application
      public function decode( $cipher_text ) {
        // set up the environment
        $td      = mcrypt_module_open( MCRYPT_BLOWFISH, '', MCRYPT_MODE_ECB, '' );
        $key     = substr( self::KEY, 0, mcrypt_enc_get_key_size( $td ) );
        $iv_size = mcrypt_enc_get_iv_size( $td );
        $iv      = mcrypt_create_iv( $iv_size, MCRYPT_RAND );
    
        if( mcrypt_generic_init( $td, $key, $iv ) != -1 ) {
          $plain_text = mdecrypt_generic( $td, pack( "H*" , $cipher_text ) );
          // clean up the mcrypt environment
          mcrypt_generic_deinit( $td );
          mcrypt_module_close( $td );
        }
    
        // remove NUL which maybe added by padding the plain_text
        return rtrim( $plain_text, "\0" );
      }
    

    この方法では、データベースとソース コードにアクセスできる人だけがパスワードを解読できます。欠点としては、アプリケーションがより複雑になり、パフォーマンスへの影響がわずかになります。また、他の対称ブロック暗号も使用できます。

そして最も重要なことは、単純なパスワードを決して保存しないことです。

于 2012-07-16T19:58:18.377 に答える