【问题标题】:Using defined security variables inside a function在函数中使用定义的安全变量
【发布时间】:2013-01-24 23:59:07
【问题描述】:

我发现我不应该对敏感数据使用像 global $auth_key 这样的全局变量(如果这不是真的,请纠正我。)所以我想使用定义的变量来存储安全密钥。

config.php 内部定义了盐键。

define('AUTH_KEY','::~K~UC*[tlu4Eq/]Lm|h');

define('SECURE_AUTH_KEY', 'QsTMvbV+tuU{K26!]J2');

encryption.php 中包含加密函数,其中AUTH_KEYSECURE_AUTH_KEY 将在其中使用。

function encrypt_text($value) {
   if(!$value) return false;
   $crypttext = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, **AUTH_KEY_HERE**, $value, MCRYPT_MODE_ECB, **SECURE_AUTH_KEY_HERE**);
   return trim(base64_encode($crypttext));
}

function decrypt_text($value) {
   if(!$value) return false;
   $crypttext = base64_decode($value);
   $decrypttext = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, **AUTH_KEY_HERE**, $crypttext, MCRYPT_MODE_ECB, **SECURE_AUTH_KEY_HERE**);
   return trim($decrypttext);
}

有没有办法做到这一点?或您可以推荐的任何其他解决方案?请注意,这些密钥对于加密敏感信息非常重要。

另外,还有一个问题,在 mcrypt 上使用的密钥的最大长度是多少?

谢谢您,期待您的回复。

【问题讨论】:

    标签: php mcrypt


    【解决方案1】:

    更新 (27/09/17):

    自从 PHP 7.1.0 起,mcrypt_encrypt 已被弃用。我使用openssl 添加了一个简单的加密/解密。

    function encrypt($string, $key = 'PrivateKey', $secret = 'SecretKey', $method = 'AES-256-CBC') {
        // hash
        $key = hash('sha256', $key);
        // create iv - encrypt method AES-256-CBC expects 16 bytes
        $iv = substr(hash('sha256', $secret), 0, 16);
        // encrypt
        $output = openssl_encrypt($string, $method, $key, 0, $iv);
        // encode
        return base64_encode($output);
    }
    
    function decrypt($string, $key = 'PrivateKey', $secret = 'SecretKey', $method = 'AES-256-CBC') {
        // hash
        $key = hash('sha256', $key);
        // create iv - encrypt method AES-256-CBC expects 16 bytes
        $iv = substr(hash('sha256', $secret), 0, 16);
        // decode
        $string = base64_decode($string);
        // decrypt
        return openssl_decrypt($string, $method, $key, 0, $iv);
    }
    
    $str = 'Encrypt this text';
    echo "Plain: " .$str. "\n";
    
    // encrypt
    $encrypted_str = encrypt($str);
    echo "Encrypted: " .$encrypted_str. "\n";
    
    // decrypt
    $decrypted_str = decrypt($encrypted_str);
    echo "Decrypted: " .$decrypted_str. "\n";
    

    在您的示例中,您使用的是相同的初始化向量 **SECURE_AUTH_KEY_HERE**,当您可以允许 PHP 以这种方式为您创建 iv 时,您只需要定义 1 个 SECURE_KEY。

    <?php 
    define('SECURE_KEY',md5('your secret key'));
    /**
    * Encrypt a value
    */
    function encrypt($str){
        $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
        $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
        return mcrypt_encrypt(MCRYPT_RIJNDAEL_256, SECURE_KEY, $str, MCRYPT_MODE_ECB, $iv);
    }
    /**
    * Decrypt a value
    */
    function decrypt($str){
        $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
        $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
        return trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, SECURE_KEY, $str, MCRYPT_MODE_ECB, $iv));
    }
    
    
    //32
    $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
    
    //Create an initialization vector (IV) from a random source 
    $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
    
    echo decrypt(encrypt('Encrypt me'));
    ?>
    

    【讨论】:

      【解决方案2】:

      使用constant 就像使用变量一样,只是没有美元符号。

      $crypttext = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, AUTH_KEY, $value, MCRYPT_MODE_ECB, SECURE_AUTH);
      

      在这种方法中没有什么比使用global 关键字更安全了。虽然这种方法是首选。通过使用常量,您说这是我将在整个应用程序中使用的静态值。另一方面,不得不使用global 通常只是糟糕的设计或懒惰的结果。它会导致代码难以遵循,滥用作用域试图完成的任务。

      密钥长度取决于使用的加密算法。 RTM。

      【讨论】:

      【解决方案3】:

      虽然选择常量比普通变量更可取,但这种信息最好存储在配置文件中而不是您的代码中。

      此外,为了更好地重用并避免将这些全局值放在它周围,封装功能是一个更好的主意:

      class MyCrypto
      {
          private $key;
          private $cipher;
          private $mode;
      
          public function __construct($key, $cipher, $mode = "cbc")
          {
             $this->key = $key;
             $this->cipher = $cipher;
             $this->mode = $mode;
          }
      
          public function generate_salt()
          {
              return mcrypt_create_iv(
                  mcrypt_get_iv_size($this->cipher, $this->mode), 
                  MCRYPT_DEV_URANDOM
              );
          }
      
          public function encrypt($data) { ... }
      
          public function decrypt($data) { ... }
      }
      

      我添加了用于每个加密操作的盐生成器功能;

      最后,我建议使用 CBC 模式 - MCRYPT_MODE_CBC

      【讨论】:

        【解决方案4】:

        通常:记录者越多,加密越强。其次,除非你的数据很短,否则不要使用ECB,你应该使用CBC或更强的东西。第三:使用盐或初始化向量。最后阅读:https://www.owasp.org/index.php/Cryptographic_Storage_Cheat_Sheet

        【讨论】:

        • +1 不是因为它是专门针对该问题的一个很好的答案,而是因为 OP 真的可以使用您链接的 OWASP 备忘单。
        【解决方案5】:

        是的,您可以像现在一样使用define 变量,请参阅示例

         define('AUTH_KEY','::~K~UC*[tlu4Eq/]Lm|h');
        
         function abc()
         {
          echo AUTH_KEY;
         }
        
         abc();  // ::~K~UC*[tlu4Eq/]Lm|h
        

        http://codepad.viper-7.com/tUAg6D

        【讨论】:

          猜你喜欢
          • 2014-04-20
          • 2011-08-12
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-12-08
          相关资源
          最近更新 更多