使用 Zend_Mail_Transport_Smtp 和一个 MD5 哈希值作为密码

Posted

技术标签:

【中文标题】使用 Zend_Mail_Transport_Smtp 和一个 MD5 哈希值作为密码【英文标题】:Using Zend_Mail_Transport_Smtp with an MD5-Hashed value as password 【发布时间】:2012-07-15 05:11:15 【问题描述】:

我想为我的网络应用程序的用户提供使用我们的 smtp 服务器发送电子邮件的可能性。

用户帐户的密码是 md5-hased 并且 smtp-server 正在对接收到的值进行哈希处理以检查正确的用户名密码组合。

现在我正在寻找一种设置 Zend_Mail_Transport_Smtp 的好方法 - 我显然需要纯文本密码并将其转发到 smtp-server,然后将其转换为 md5-hash。 但这意味着我必须将用户密码以明文形式存储在某处,我想避免这种情况。

有没有关于如何使用 zend 框架设置 webmailer 的最佳实践?

我唯一的想法是将未经哈希处理的密码保存在会话中(我的应用程序中的用户帐户与邮件服务器帐户相关联),但必须有更好的方法来处理这种情况

【问题讨论】:

你的问题解决了吗?? 【参考方案1】:

您可以做的是将密码以编码格式存储在数据库中,并在需要时在应用程序中对其进行解码。不幸的是,MD5 只是一个散列函数,您无法解码为纯密码。我知道三种方法可以做到这一点:

    替换字母:

    您可以使用 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() 或类似的东西,因为看到密码的人很容易猜到。

    无需密钥即可解码/编码:

    另一种方法是使用函数对密码进行解码/编码,不需要像Base64这样的密钥:

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

    比上面的要好一点,但我只会将它用于测试目的,因为它很容易实现和使用。

    使用密钥解码/编码:

    更好的方法是使用密钥和对称分组密码,例如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" );
      
    

    通过这种方式,只有有权访问数据库和源代码的人才能解码密码。不利的一面是,您有一个更复杂的应用程序和一点点性能影响。您也可以使用其他对称分组密码。

最重要的是:永远不要存储纯密码。

【讨论】:

以上是关于使用 Zend_Mail_Transport_Smtp 和一个 MD5 哈希值作为密码的主要内容,如果未能解决你的问题,请参考以下文章

在使用加载数据流步骤的猪中,使用(使用 PigStorage)和不使用它有啥区别?

今目标使用教程 今目标任务使用篇

Qt静态编译时使用OpenSSL有三种方式(不使用,动态使用,静态使用,默认是动态使用)

MySQL db 在按日期排序时使用“使用位置;使用临时;使用文件排序”

使用“使用严格”作为“使用强”的备份

Kettle java脚本组件的使用说明(简单使用升级使用)