代码之家  ›  专栏  ›  技术社区  ›  blinking_eyes

如何获取openssl_decrypt二进制输出?

  •  3
  • blinking_eyes  · 技术社区  · 10 年前

    我正在尝试使用openssl_encrypt/openssl_decrypt对一些数据进行加密/解密。目的如下:用户在GUI中输入一些数据,这些数据被加密并存储在数据库中。稍后,将仅针对特定用户配置文件检索和解密它。

    加密部分工作正常,因为我遵循了一位同事的建议,即将输出包装到bin2hex函数中。

    这是我编写的测试此函数的示例代码:

    菲律宾比索

    function encrypt($string) {
    
    $cypher = 'aes-256-cbc';
    $key = 's7aBkf4Ypn59bWviQziPDXyPasdaYlhQ';
    
    $ivsize = openssl_cipher_iv_length($cypher);
    $iv = openssl_random_pseudo_bytes($ivsize); 
    
    $encripted = openssl_encrypt(
            $string, $cypher, $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $iv
    );
    
    return $iv . $encripted;
    }
    
    function decrypt($string) {
    
    $cypher = 'aes-256-cbc';
    $key = 's7aBkf4Ypn59bWviQziPDXyPasdaYlhQ'; 
    
    $ivsize = openssl_cipher_iv_length($cypher);
    $iv = mb_substr($string, 0, $ivsize, '8bit');
    $decrypted = mb_substr($string, $ivsize, null, '8bit');
    
    $output = openssl_decrypt(
                    $decrypted, $cifrado, $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $iv
    );
    
    return $output;
    }
    

    HTML格式:

    <!doctype html>
     <html>
        <head><title>TEST</title></head>
        <body>
            <div style='margin-left:250px;'>
                <form action="test.php" method="POST">
                Encrypt
                <input type="text" name="encrypt" value=''/>
                <input type="submit" name="send" value='Send'/>
                <br/><br/>
                <?php
                if (isset($_POST['encrypt']) && !empty($_POST['encrypt'])) {
                    echo 'encrypted string: ' . bin2hex(encrypt($_POST['encrypt']));
                }
                ?>
                <br/>
                <br/>
                Decrypt
                <input type="text" name="decrypt" value=''/>
                <input type="submit" name="send" value='Send'/>
                <br/><br/>
                <?php
                if (isset($_POST['decrypt']) && !empty($_POST['decrypt'])) {
                    echo 'decrypted string: ' . decrypt($_POST['decrypt']);
                    var_dump(decrypt($_POST['decrypt']));
                }
                ?>
            </form>
    </body>
    

    如有任何想法或帮助,我们将不胜感激。

    我的PHP版本是5.4.45-0+deb7u2。

    提前谢谢。

    1 回复  |  直到 10 年前
        1
  •  4
  •   Ryan Vincent Gaurav Sirauthiya    6 年前

    根据@Zaph的备注进行更新。

    @Zaph:PKCS#7填充是一般填充,应该使用。事实证明,PHP OpenSSL的默认值是PKCS#7。因此,不要添加任何填充选项,您会得到正确的结果。

    Openssl_encrypt() Openssl_decrypt()

    我使用的是PHP 5.4.4。

    因此,唯一需要的选项是:OPENSSL_RAW_DATA。

    请注意,IV(初始化向量)每次都会更改,并存储在输出字符串中。为什么?如果您提供相同的字符串和密码,则每次都肯定是不同的输出字符串。

    base64_encoded

    演示地点: ideone.com

    ###加密: /** *加密字符串 * *
    *@Param字符串$data * *@return字符串-base64_encoded
    */

      $cypher = 'aes-256-cbc';  
      $ivSize  = openssl_cipher_iv_length($cypher);
      $ivData  = openssl_random_pseudo_bytes($ivSize);
      
      $encripted = openssl_encrypt($data, 
                                  $cypher, 
                                  $key, 
                                  OPENSSL_RAW_DATA, 
                                  $ivData);
    
                                
      return base64_encode($ivData  . $encripted);
    }
    

    ###解密:

    /**
     * Decrypt a string
     * 
     * @Param string $data 
     * @Param string $key
     * 
     * @return string  - original text   
     */ 
    function decrypt($data, $key) {
    
      $cypher = 'aes-256-cbc';  
      $ivSize  = openssl_cipher_iv_length($cypher);
    
      $data = base64_decode($data);
      $ivData   = substr($data, 0, $ivSize);
       
      $encData = substr($data, $ivSize);
    
      $output = openssl_decrypt($encData, 
                                $cypher, 
                                $key, 
                                OPENSSL_RAW_DATA, 
                                $ivData);
      return $output;
    }
    

    运行它:

    $srcText = "Hello World! - " . uniqid();
    $key    = 's7aBkf4Ypn59bWviQziPDXyPasdaYlhQ';
    
    $srcEncrypted  = '';
    $srcDecrypted  = '';
    
    $srcEncrypted = encrypt($srcText, $key);
    
    $srcDecrypted = decrypt($srcEncrypted, $key);
    
    var_dump($srcText, 
             $srcEncrypted, 
             $srcDecrypted, 
             $srcDecrypted == $srcText);
    

    ###输出示例:

    string 'Hello World! - 5776adf944c52' (length=28)
    
    string 'NOjIIMM0visDbJPmBsAMgH+OQbYiReLBSvzg5JVZTMUOCAtk3CO7FBNs/Dn/vE9s' (length=64)
    
    string 'Hello World! - 5776adf944c52' (length=28)
    
    boolean true
    
    推荐文章