2017-02-20 1 views
2

현재 Mcrypt를 OpenSSL로 대체하는 과정에 있습니다. 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' man pages] (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 인증 암호화 및 해독] (http://wiki.openssl.org/index.php/EVP_Authenticated_Encryption_and_Decryption)을 참조하십시오.) OpenSSL 위키에. – jww

+0

괜찮아요, 정확히 내가 뭘 필요하지만, PHP에서 이것을 어떻게 호출합니까? – herriekrekel

답변

0

불행히도 cipher blockSize를 제공하는 API가 없습니다. 이 실제로 인 경우 blockSize (알고리즘 당)를 하드 코딩해야합니다.

그러나 일반적인 응용 프로그램은 단일 암호화 알고리즘 만 지원하면됩니다.이 경우 사용자는 블록 크기가 무엇인지 이미 알고 있어야합니다.

또한, 내가 mcrypt_get_block_size() 위해 했어 유일한 사용 사례, mcrypt_enc_get_block_size()는 OpenSSL을 이미 블록 암호 알고리즘의 기본에 의해 수행 PKCS # 7 패딩이다. 그래서 당신이 이것을 전혀 필요로하지 않을 수도 있습니다.

+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()에서 bruteforces입니다.

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)); 

데이터 블록 크기에 패딩됩니다 그것은 기본적으로, 빈 문자열을 암호화하고있어, 결과의 길이를 확인.

몇 가지 다른 방법으로 테스트 해봤는데 제대로 작동하는 것 같습니다.

관련 문제