2017-02-20 73 views
2

我目前正在使用OpenSSL替換Mcrypt,因爲Mcrypt將在PHP 7.1中被棄用。我需要的是一種方法來獲得像mcrypt_get_block_size()這樣的算法的塊大小。OpenSSL相當於mcrypt_get_block_size

我想知道是否有相當於mcrypt_get_block_size()的功能,但它的記錄相當糟糕,似乎無法找到它。

+3

在OpenSSL中,您使用'EVP_CIPHER_CTX'創建了一個上下文。然後,調用'EVP_CIPHER_block_size'來獲取塊大小。它在['EVP_EncryptInit'手冊頁](https://www.openssl.org/docs/man1.1.0/crypto/EVP_CIPHER_block_size.html)中記錄。另請參閱[EVP對稱加密和解密](http://wiki.openssl.org/index.php/EVP_Symmetric_Encryption_and_Decryption)和[EVP Authenticated Encryption and Decryption](http://wiki.openssl.org/index.php/EVP_Authenticated_Encryption_and_Decryption )在OpenSSL wiki上。 – jww

+0

好吧,那正是我需要的東西我怎樣在PHP中調用這個呢? – herriekrekel

回答

0

不幸的是,沒有一個可以給你加密blockSize的API。如果你真的需要,你必須對blockSize(每個算法)進行硬編碼。

但是,典型的應用程序只需要支持一種加密算法,在這種情況下,您應該已經知道塊大小是否適合您的情況。

並且也只有用例我已經爲mcrypt_get_block_size()mcrypt_enc_get_block_size()是PKCS#7填充,OpenSSL將默認的塊加密算法已經這樣做了。所以可能是這種情況,你根本不需要這個。

+0

需要塊大小來確定IV大小。 – zaph

+0

@zaph這裏有'openssl_cipher_iv_length()'。 – Narf

+0

我不明白這是什麼令人困惑...... IV與塊大小不同,'openssl_cipher_iv_length()'是PHP公開的函數。 – Narf

1

以下函數可以用來替代PHP> = 5.4.0。 它只是在openssl_encrypt()之外強化了塊長度。

if (!function_exists('openssl_cipher_block_length')) { 
    /** 
    * Returns the block length for a given cipher. 
    * 
    * @param string $cipher 
    *  A cipher method (see openssl_get_cipher_methods()). 
    * 
    * @retval int 
    *  The cipher's block length. 
    *  Returns false if the actual length cannot be determined. 
    *  Returns 0 for some cipher modes that do not use blocks 
    *  to encrypt data. 
    * 
    * @note 
    *  PHP >= 5.4.0 is required for this function to work. 
    */ 
    function openssl_cipher_block_length($cipher) 
    { 
     $ivSize = @openssl_cipher_iv_length($cipher); 

     // Invalid or unsupported cipher. 
     if (false === $ivSize) { 
      return false; 
     } 

     $iv = str_repeat("a", $ivSize); 

     // Loop over possible block sizes, from 1 upto 1024 bytes. 
     // The upper limit is arbitrary but high enough that is 
     // sufficient for any current & foreseeable cipher. 
     for ($size = 1; $size < 1024; $size++) { 
      $output = openssl_encrypt(
       // Try varying the length of the raw data 
       str_repeat("a", $size), 

       // Cipher to use 
       $cipher, 

       // OpenSSL expands the key as necessary, 
       // so this value is actually not relevant. 
       "a", 

       // Disable data padding: php_openssl will return false 
       // if the input data's length is not a multiple 
       // of the block size. 
       // 
       // We also pass OPENSSL_RAW_DATA so that PHP does not 
       // base64-encode the data (since we just throw it away 
       // afterwards anyway) 
       OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, 

       // Feed it with an IV to avoid nasty warnings. 
       // The actual value is not relevant as long as 
       // it has the proper length. 
       $iv 
      ); 

      if (false !== $output) { 
       return $size; 
      } 
     } 

     // Could not determine the cipher's block length. 
     return false; 
    } 
} 
0

我認爲你可以做這樣的事情:

$method = 'AES-256-CBC'; 
$iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length($method)); 
$block_size = strlen(openssl_encrypt('', $method, '', OPENSSL_RAW_DATA, $iv)); 

它基本上加密一個空字符串,並作爲數據將被填充到塊大小,檢查結果的長度。

我用一些不同的方法測試過它,它似乎正常工作。