Defuse\Crypto\KeyOrPassword::deriveKeys PHP Method

deriveKeys() public method

Derives authentication and encryption keys from the secret, using a slow key derivation function if the secret is a password.
public deriveKeys ( string $salt ) : Defuse\Crypto\DerivedKeys
$salt string
return Defuse\Crypto\DerivedKeys
    public function deriveKeys($salt)
    {
        if (Core::ourStrlen($salt) !== Core::SALT_BYTE_SIZE) {
            throw new Ex\EnvironmentIsBrokenException('Bad salt.');
        }
        if ($this->secret_type === self::SECRET_TYPE_KEY) {
            $akey = Core::HKDF(Core::HASH_FUNCTION_NAME, $this->secret->getRawBytes(), Core::KEY_BYTE_SIZE, Core::AUTHENTICATION_INFO_STRING, $salt);
            $ekey = Core::HKDF(Core::HASH_FUNCTION_NAME, $this->secret->getRawBytes(), Core::KEY_BYTE_SIZE, Core::ENCRYPTION_INFO_STRING, $salt);
            return new DerivedKeys($akey, $ekey);
        } elseif ($this->secret_type === self::SECRET_TYPE_PASSWORD) {
            /* Our PBKDF2 polyfill is vulnerable to a DoS attack documented in
             * GitHub issue #230. The fix is to pre-hash the password to ensure
             * it is short. We do the prehashing here instead of in pbkdf2() so
             * that pbkdf2() still computes the function as defined by the
             * standard. */
            $prehash = \hash(Core::HASH_FUNCTION_NAME, $this->secret, true);
            $prekey = Core::pbkdf2(Core::HASH_FUNCTION_NAME, $prehash, $salt, self::PBKDF2_ITERATIONS, Core::KEY_BYTE_SIZE, true);
            $akey = Core::HKDF(Core::HASH_FUNCTION_NAME, $prekey, Core::KEY_BYTE_SIZE, Core::AUTHENTICATION_INFO_STRING, $salt);
            /* Note the cryptographic re-use of $salt here. */
            $ekey = Core::HKDF(Core::HASH_FUNCTION_NAME, $prekey, Core::KEY_BYTE_SIZE, Core::ENCRYPTION_INFO_STRING, $salt);
            return new DerivedKeys($akey, $ekey);
        } else {
            throw new Ex\EnvironmentIsBrokenException('Bad secret type.');
        }
    }

Usage Example

Beispiel #1
0
 /**
  * Decrypts a ciphertext to a string with either a key or a password.
  *
  * @param string        $ciphertext
  * @param KeyOrPassword $secret
  * @param bool          $raw_binary
  *
  * @throws Ex\EnvironmentIsBrokenException
  * @throws Ex\WrongKeyOrModifiedCiphertextException
  *
  * @return string
  */
 private static function decryptInternal($ciphertext, KeyOrPassword $secret, $raw_binary)
 {
     RuntimeTests::runtimeTest();
     if (!$raw_binary) {
         try {
             $ciphertext = Encoding::hexToBin($ciphertext);
         } catch (Ex\BadFormatException $ex) {
             throw new Ex\WrongKeyOrModifiedCiphertextException('Ciphertext has invalid hex encoding.');
         }
     }
     if (Core::ourStrlen($ciphertext) < Core::MINIMUM_CIPHERTEXT_SIZE) {
         throw new Ex\WrongKeyOrModifiedCiphertextException('Ciphertext is too short.');
     }
     // Get and check the version header.
     $header = Core::ourSubstr($ciphertext, 0, Core::HEADER_VERSION_SIZE);
     if ($header !== Core::CURRENT_VERSION) {
         throw new Ex\WrongKeyOrModifiedCiphertextException('Bad version header.');
     }
     // Get the salt.
     $salt = Core::ourSubstr($ciphertext, Core::HEADER_VERSION_SIZE, Core::SALT_BYTE_SIZE);
     if ($salt === false) {
         throw new Ex\EnvironmentIsBrokenException();
     }
     // Get the IV.
     $iv = Core::ourSubstr($ciphertext, Core::HEADER_VERSION_SIZE + Core::SALT_BYTE_SIZE, Core::BLOCK_BYTE_SIZE);
     if ($iv === false) {
         throw new Ex\EnvironmentIsBrokenException();
     }
     // Get the HMAC.
     $hmac = Core::ourSubstr($ciphertext, Core::ourStrlen($ciphertext) - Core::MAC_BYTE_SIZE, Core::MAC_BYTE_SIZE);
     if ($hmac === false) {
         throw new Ex\EnvironmentIsBrokenException();
     }
     // Get the actual encrypted ciphertext.
     $encrypted = Core::ourSubstr($ciphertext, Core::HEADER_VERSION_SIZE + Core::SALT_BYTE_SIZE + Core::BLOCK_BYTE_SIZE, Core::ourStrlen($ciphertext) - Core::MAC_BYTE_SIZE - Core::SALT_BYTE_SIZE - Core::BLOCK_BYTE_SIZE - Core::HEADER_VERSION_SIZE);
     if ($encrypted === false) {
         throw new Ex\EnvironmentIsBrokenException();
     }
     // Derive the separate encryption and authentication keys from the key
     // or password, whichever it is.
     $keys = $secret->deriveKeys($salt);
     if (self::verifyHMAC($hmac, $header . $salt . $iv . $encrypted, $keys->getAuthenticationKey())) {
         $plaintext = self::plainDecrypt($encrypted, $keys->getEncryptionKey(), $iv, Core::CIPHER_METHOD);
         return $plaintext;
     } else {
         throw new Ex\WrongKeyOrModifiedCiphertextException('Integrity check failed.');
     }
 }
All Usage Examples Of Defuse\Crypto\KeyOrPassword::deriveKeys