使用PHP mcrypt和Rijndael/AES

riv*_*raz 8 php encryption cryptography aes mcrypt

我正在尝试使用来自php和密码Rijndael的mcrypt加密一些文本消息,但我不确定MCRYPT_MODE_modename(根据PHP的手册,这些是可用的"ecb","cbc","cfb","ofb"," nofb"或"stream"但我读到的确实还有一些).我不知道每个人做什么或如何使用它们.

我读了两件事,不应该使用ECB模式,也不要使用MCRYPT_RAND.他们没有解释原因.对于ECB模式,我想这是因为它总是为相同的纯文本生成相同的加密输出(可能这可以用于攻击),不知道MCRYPT_RAND(@azz 在这里提到).

我的问题是,我应该使用什么样的mcrypt模式,看到使用的php代码的例子会很棒,因为我找到的所有例子都使用了ECB.我试图加密的字符串将只包含ascii文本和可变长度,不大于500个字符.

Nig*_*Owl 16

ecb是最简单的,也有弱点,因此不推荐使用(http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation).cbc被认为比ecb强得多.其他一些可能甚至比cbc更强,但它们都是流相关的,所以cbc应该适合你的需要.

来自...... http://us.php.net/manual/en/mcrypt.constants.php ...

  • MCRYPT_MODE_ECB(电子密码本)适用于随机数据,例如加密其他密钥.由于数据短且随机,ECB的缺点具有有利的负面影响.
  • MCRYPT_MODE_CBC(密码块链接)特别适用于加密大大超过ECB的安全性的文件.
  • MCRYPT_MODE_CFB(密码反馈)是加密单字节必须加密的字节流的最佳模式.
  • MCRYPT_MODE_OFB(输出反馈,8位)与CFB相当,但可用于无法容忍错误传播的应用中.它不安全(因为它以8位模式运行)因此不建议使用它.
  • MCRYPT_MODE_NOFB(输出反馈,以nbit为单位)与OFB相当,但更安全,因为它根据算法的块大小进行操作.
  • MCRYPT_MODE_STREAM是一种额外的模式,包括一些流算法,如"WAKE"或"RC4".

我不确定为什么建议使用MCRYPT_RAND,但可能是因为许多系统上的系统随机数生成器不被认为是真正随机的.根据您的系统和PHP版本,只有两种选择,它们可能不可用.来自... http://php.net/manual/en/function.mcrypt-create-iv.php ...

  • IV源可以是MCRYPT_RAND(系统随机数发生器),MCRYPT_DEV_RANDOM(从/ dev/random读取数据)和MCRYPT_DEV_URANDOM(从/ dev/urandom读取数据).在5.3.0之前,MCRYPT_RAND是Windows上唯一支持的.

下面的代码只是一个快速示例.它有效,但我不能证明它的力量.


<?php

// Test code

    $objEncManager = new DataEncryptor();

    $sensitiveData = "7890";
    echo "Raw Data: _" . $sensitiveData . "_<br><br>";

    $encryptedData = $objEncManager->mcryptEncryptString( $sensitiveData );
    echo "Enc Data: _" . $encryptedData . "_<br><br>";
    echo "Enc Data length: " . strlen( $encryptedData) . "<br><br>";

    $decryptedData = $objEncManager->mcryptDecryptString( $encryptedData, $objEncManager->lastIv );
    echo "D-enc Data: _" . $decryptedData . "_<br><br>";

    echo "IV: _" . $objEncManager->lastIv . "_<br><br>";


/*
 * Note: These functions do not accurately handle cases where the data 
 * being encrypted have trailing whitespace so the data
 *       encrypted by them must not have any. Leading whitespace is okay.
 *  
 * Note: If your data needs to be passed through a non-binary safe medium you should
 * base64_encode it but this makes the data about 33% larger.
 * 
 * Note: The decryption IV must be the same as the encryption IV so the encryption
 * IV must be stored or transmitted with the encrypted data.
 * From (http://php.net/manual/en/function.mcrypt-create-iv.php)... 
 * "The IV is only meant to give an alternative seed to the encryption routines. 
 * This IV does not need to be secret at all, though it can be desirable. 
 * You even can send it along with your ciphertext without losing security."
 * 
 * Note: These methods don't do any error checking on the success of the various mcrypt functions
 */
class DataEncryptor
{
    const MY_MCRYPT_CIPHER        = MCRYPT_RIJNDAEL_256;
    const MY_MCRYPT_MODE          = MCRYPT_MODE_CBC;
    const MY_MCRYPT_KEY_STRING    = "1234567890-abcDEFGHUzyxwvutsrqpo"; // This should be a random string, recommended 32 bytes

    public  $lastIv               = '';


    public function __construct()
    {
        // do nothing
    }


    /**
     * Accepts a plaintext string and returns the encrypted version
     */
    public function mcryptEncryptString( $stringToEncrypt, $base64encoded = true )
    {
        // Set the initialization vector
            $iv_size      = mcrypt_get_iv_size( self::MY_MCRYPT_CIPHER, self::MY_MCRYPT_MODE );
            $iv           = mcrypt_create_iv( $iv_size, MCRYPT_RAND );
            $this->lastIv = $iv;

        // Encrypt the data
            $encryptedData = mcrypt_encrypt( self::MY_MCRYPT_CIPHER, self::MY_MCRYPT_KEY_STRING, $stringToEncrypt , self::MY_MCRYPT_MODE , $iv );

        // Data may need to be passed through a non-binary safe medium so base64_encode it if necessary. (makes data about 33% larger)
            if ( $base64encoded ) {
                $encryptedData = base64_encode( $encryptedData );
                $this->lastIv  = base64_encode( $iv );
            } else {
                $this->lastIv = $iv;
            }

        // Return the encrypted data
            return $encryptedData;
    }


    /**
     * Accepts a plaintext string and returns the encrypted version
     */
    public function mcryptDecryptString( $stringToDecrypt, $iv, $base64encoded = true )
    {
        // Note: the decryption IV must be the same as the encryption IV so the encryption IV must be stored during encryption

        // The data may have been base64_encoded so decode it if necessary (must come before the decrypt)
            if ( $base64encoded ) {
                $stringToDecrypt = base64_decode( $stringToDecrypt );
                $iv              = base64_decode( $iv );
            }

        // Decrypt the data
            $decryptedData = mcrypt_decrypt( self::MY_MCRYPT_CIPHER, self::MY_MCRYPT_KEY_STRING, $stringToDecrypt, self::MY_MCRYPT_MODE, $iv );

        // Return the decrypted data
            return rtrim( $decryptedData ); // the rtrim is needed to remove padding added during encryption
    }


}
?>