首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用MCRYPT...Inconsistent结果在PHP中进行加密/解密

使用MCRYPT...Inconsistent结果在PHP中进行加密/解密
EN

Stack Overflow用户
提问于 2014-02-24 15:17:31
回答 1查看 281关注 0票数 1

我一直在使用您的站点来帮助我解决各种编程问题,我终于遇到了一个在其他地方找不到解决的问题。

我正尝试在PHP中使用mcrypt来加密和解密存储在我客户网站上的密码。这些密码用于外部网站,因此必须加密/解密,而不是哈希。我目前正在将他们的旧框架Legato更新到更新的Yii框架。使用类文件中概述的加密方案将密码存储在当前数据库中。该计划的内容如下:

代码语言:javascript
复制
<?php

//--------------------------------------------------------------------------
// Name: Legato_Encryption
// Desc: An encryption engine. Contains functions to encrypt and decrypt
//       text.
//--------------------------------------------------------------------------
class Legato_Encryption
{

    //------------------------------------------------------------------------
    // Public Variables
    //------------------------------------------------------------------------
    private $_cypher; // The cypher algorithm.
    private $_mode; // The encryption mode.
    private $_td; // The TD for mcrypt.
    private $_private_key; // The private key.

    //------------------------------------------------------------------------
    // Public Member Functions
    //------------------------------------------------------------------------
    //------------------------------------------------------------------------
    // Name: __construct()
    // Desc: Class constructor.
    //------------------------------------------------------------------------
    public function __construct( $private_key, $cypher = 'blowfish', $mode = 'cfb' )
    {

        // Make sure everything was filled in.
        if ( $private_key == "" || $cypher == "" || $mode == "" )
        {
            Legato_Debug_Debugger::add_item( 'Invalid parameters for encryption. NULL passed in.' );
            return false;
        }

        // Assign the class variables to those passed in.
        $this->_cypher = $cypher;
        $this->_mode = $mode;

        // Get the TD.
        $this->_td = mcrypt_module_open( $this->_cypher, '', $this->_mode, '' );

        // Get the expected key size based on mode and cipher  .
        $expected_key_size = mcrypt_enc_get_key_size( $this->_td );

        // We dont need to know the real key, we just need to be able to confirm a hashed version.
        $this->_private_key = substr( md5($private_key), 0, $expected_key_size );

    }

    //------------------------------------------------------------------------
    // Name: encrypt()
    // Desc: Encrypts the plaint text passed in.
    //------------------------------------------------------------------------
    public function encrypt( $plaintext )
    {

        // Create the IV.
        $iv = mcrypt_create_iv( mcrypt_enc_get_iv_size($this->_td), MCRYPT_RAND );

        // Initialize the mcrypt engine.
        mcrypt_generic_init( $this->_td, $this->_private_key, $iv );

        // Encode/encrypt the text.
        $crypttext = base64_encode( mcrypt_generic($this->_td, $plaintext) );

        // Shut down mcrypt.
        mcrypt_generic_deinit( $this->_td );

        // Return the iv prefixed to the encrypted text.
        return $iv . $crypttext;

    }

    //------------------------------------------------------------------------
    // Name: decrypt()
    // Desc: Decrypts the encrypted text passed in.
    //------------------------------------------------------------------------
    public function decrypt( $crypttext )
    {

        // Get the iv from the beginning of the encrypted text.
        $iv_size = mcrypt_enc_get_iv_size( $this->_td );
        $iv = substr( $crypttext, 0, $iv_size );

        // Get the encrypted text.
        $crypttext = substr( $crypttext, $iv_size );
        $plaintext = '';

        // Attempt to decrypt the text.
        if ( $iv )
        {

            // Initialize the mcrypt engine.
            mcrypt_generic_init( $this->_td, $this->_private_key, $iv );

            // Decode the crypted text, then decrypt it, then trim it of whitespaces.
            $plaintext = trim( mdecrypt_generic($this->_td, base64_decode($crypttext)) );

            // Shut down mcrypt.
            mcrypt_generic_deinit( $this->_td );

        } // End if $iv true.

        // Return the plain text.
        return $plaintext;

    }

}

我的问题是,在实时服务器上使用该类,它可以准确地加密和解密密码。如果我提取该代码,将其粘贴到新文件中,并以与相同输入完全相同的方式使用它,它将返回一个不同的字符串,通常带有"?“字符(不是问号字符,而是web浏览器无法解释的字符)。

例如,Legato_Encryption('hello','twofish').encrypt('hello')会返回一些与我在Yii_Encryption('hello','twofish').encrypt('hello')中使用它完全不同的东西。这是相同的代码和相同的过程,使用相同的parameters...how,它可以返回不同的值吗?我相信encrypt()函数似乎在每次执行时都会生成随机值,但是decrypt()应该返回正确的字符串。

有没有人看到这个代码可能会变得不稳定或产生不一致的结果?我在这个问题上花费了太多的时间,因为这里关于类似问题的许多其他帖子都没有产生成功的结果。

EN

回答 1

Stack Overflow用户

发布于 2014-02-24 23:37:48

听起来你遇到了一个由不同的OS / PHP版本引起的“可移植散列”问题。可能需要以编程方式升级散列(我建议使用phpNode的Yii密码行为扩展)一次,然后使用更新的散列系统……

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21981243

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档