public function encrypt($data)
    {
        /** @var string $binary */
        $binary = $this->config('binary');

        if ($binary) {
            $this->_binary = $binary;
        }

        if (!is_executable($this->_binary)) {
            throw new Exception(sprintf('pdftk binary is not found or not executable: %s', $this->_binary));
        }

        $arguments = [];

        $ownerPassword = $this->_Pdf->ownerPassword();
        if ($ownerPassword !== null) {
            $arguments['owner_pw'] = escapeshellarg($ownerPassword);
        }

        $userPassword = $this->_Pdf->userPassword();
        if ($userPassword !== null) {
            $arguments['user_pw'] = escapeshellarg($userPassword);
        }

        $allowed = $this->_buildPermissionsArgument();
        if ($allowed) {
            $arguments['allow'] = $allowed;
        }

        if (!$ownerPassword && !$userPassword) {
            throw new Exception('Crypto: Required to configure atleast an ownerPassword or userPassword');
        }

        if ($ownerPassword == $userPassword) {
            throw new Exception('Crypto: ownerPassword and userPassword cannot be the same');
        }

        $command = sprintf('%s - output - %s', $this->_binary, $this->_buildArguments($arguments));

        $descriptorspec = [
            0 => ['pipe', 'r'], // feed stdin of process from this file descriptor
            1 => ['pipe', 'w'], // Note you can also grab stdout from a pipe, no need for temp file
            2 => ['pipe', 'w'], // stderr
        ];

        $prochandle = proc_open($command, $descriptorspec, $pipes);

        fwrite($pipes[0], $data);
        fclose($pipes[0]);

        $stdout = stream_get_contents($pipes[1]);
        fclose($pipes[1]);
        $stderr = stream_get_contents($pipes[2]);
        fclose($pipes[2]);

        $exitcode = proc_close($prochandle);

        if ($exitcode !== 0) {
            throw new Exception(sprintf('Crypto: Unknown error (exit code %d)', $exitcode));
        }

        return $stdout;
    }