<?xml version="1.0" encoding="UTF-8"?>
<!-- EN-Revision: 21994 -->
<!-- Reviewed: no -->
<sect2 id="zend.filter.set.encrypt">
    <title>Encrypt</title>

    <para>
        Dieser Filter verschlüsselt beliebige Strings mit den angegebenen Einstellungen. Hierfür
        verwendet er Adapter. Aktuell gibt es Adapter für die <classname>Mcrypt</classname> und
        <classname>OpenSSL</classname> Erweiterungen von <acronym>PHP</acronym>.
    </para>

    <para>
        Da diese zwei Verschlüsselungs-Methodologien komplett unterschiedlich arbeiten, ist auch die
        Verwendung der Adapters unterschiedlich. Man muß die Adapter den man verwenden will, bei der
        Initialisierung des Filters auswählen.
    </para>

    <programlisting language="php"><![CDATA[
// Verwenden des Mcrypt Adapters
$filter1 = new Zend_Filter_Encrypt(array('adapter' => 'mcrypt'));

// Verwendung des OpenSSL Adapters
$filter2 = new Zend_Filter_Encrypt(array('adapter' => 'openssl'));
]]></programlisting>

    <para>
        Um einen anderen Adapter zu setzen kann man auch <methodname>setAdapter()</methodname>
        verwenden, und die <methodname>getAdapter()</methodname> Methode um den aktuell gesetzten
        Adapter zu erhalten.
    </para>

    <programlisting language="php"><![CDATA[
// Verwenden des Mcrypt Adapters
$filter = new Zend_Filter_Encrypt();
$filter->setAdapter('openssl');
]]></programlisting>

    <note>
        <para>
            Wenn man die <property>adapter</property> Option nicht angibt oder setAdapter nicht
            verwendet, dann wird standardmäßig der <classname>Mcrypt</classname> Adapter verwendet.
        </para>
    </note>

    <sect3 id="zend.filter.set.encrypt.mcrypt">
        <title>Verschlüsselung mit Mcrypt</title>

        <para>
            Wenn man die <classname>Mcrypt</classname> Erweiterung installiert hat, kann man den
            <classname>Mcrypt</classname> Adapter verwenden. Dieser Adapter unterstützt bei der
            Initialisierung die folgenden Optionen:
        </para>

        <itemizedlist>
            <listitem>
                <para>
                    <emphasis>key</emphasis>: Der Verschlüsselungs-Schlüssel mit dem die Eingabe
                    verschlüsselt wird. Man benötigt den gleichen Schlüssel für die Entschlüsselung.
                </para>
            </listitem>

            <listitem>
                <para>
                    <emphasis>algorithm</emphasis>: Der Algorithmus der verwendet werden soll. Das
                    sollte einer der Algorithmus Cipher sein die man unter <ulink
                        url="http://php.net/mcrypt">PHP's Mcrypt Cipers</ulink> finden kann. Wenn er
                    nicht gesetzt wird, ist er standardmäßig 'blowfish'.
                </para>
            </listitem>

            <listitem>
                <para>
                    <emphasis>algorithm_directory</emphasis>: Das Verzeichnis in dem der Algorithmus
                    gefunden werden kann. Wenn es nicht gesetzt wird, ist es standardmäßig der Pfad
                    der in der Mcrypt Erweiterung gesetzt wurde.
                </para>
            </listitem>

            <listitem>
                <para>
                    <emphasis>mode</emphasis>: Der Verschlüsselungs Modus der verwendet werden soll.
                    Es sollte einer der Modi sein der unter <ulink url="http://php.net/mcrypt">PHP's
                    Mcrypt Modi</ulink> gefunden werden kann. Wenn er nicht gesetzt wird, ist er
                    standardmäßig 'cbc'.
                </para>
            </listitem>

            <listitem>
                <para>
                    <emphasis>mode_directory</emphasis>: Der Verzeichnis in dem der Modus gefunden
                    werden kann. Wenn es nicht gesetzt wird, ist es standardmäßig der Pfad der in
                    der <classname>Mcrypt</classname> Erweiterung gesetzt wurde.
                </para>
            </listitem>

            <listitem>
                <para>
                    <emphasis>vector</emphasis>: Der Initialisierungs Vektor der verwendet werden
                    soll. Wenn er nicht gesetzt wird, wird ein zufälliger Vektor verwende.
                </para>
            </listitem>

            <listitem>
                <para>
                    <emphasis>salt</emphasis>: Ob der Schlüssel als Salt Wert verwendet wird. Der
                    Schlüssel der für die Verschlüsselung verwendet wird, wird selbst auch
                    verschlüsselt. Der Standardwert ist <constant>FALSE</constant>.
                </para>
            </listitem>

            <listitem>
                <para>
                    <emphasis>compression</emphasis>: Ob der verschlüsselte Wert komprimiert werden
                    soll. Der Standard ist nicht komprimiert. Für Details sehen Sie unter <link
                        linkend="zend.filter.set.encrypt.openssl.compressed">Komprimierung für
                        Openssl</link> nach.
                </para>
            </listitem>
        </itemizedlist>

        <para>
            Wenn man einen String statt einem Array übergibt, wird dieser String als key Option
            verwendet.
        </para>

        <para>
            Man kan die Verschlüsselungswerte auch im Nachhinein mit den Methoden
            <methodname>getEncryption()</methodname> und <methodname>setEncryption()</methodname>
            erhalten und setzen.
        </para>

        <note>
            <para>
                Es ist zu beachten das man eine Ausnahme erhält wenn die mcrypt Erweiterung in der
                eigenen Umgebung nicht vorhanden ist.
            </para>
        </note>

        <note>
            <para>
                Man sollte auch beachten das alle Einstellungen geprüft werden wenn man eine Instanz
                erstellt oder <methodname>setEncryption()</methodname> aufruft. Wenn mcrypt ein
                Problem mit diesen Einstellungen erkennt wird eine Ausnahme geworfen.
            </para>
        </note>

        <para>
            Man kann den Verschlüsselungs Vektor durch den Aufruf von
            <methodname>getVector()</methodname> und <methodname>setVector()</methodname>
            erhalten und setzen. Ein engegebener String wird, je nach benötigter Vektorgröße des
            verwendeten Algorithmus, abgeschnitten oder aufgefüllt.
        </para>

        <note>
            <para>
                Es ist zu beachten das, wenn man keinen eigenen Vektor setzt, man den Vektor holen
                und speichern muß. Andernfalls ist man nicht in der Lage den verschlüsselten String
                wieder zu dekodieren.
            </para>
        </note>

        <programlisting language="php"><![CDATA[
// Verwendet die standardmäßigen Blowfish Einstellungen
$filter = new Zend_Filter_Encrypt('myencryptionkey');

// Setzt einen eigenen Vektor, andernfalls muß man getVector()
// ausrufen und diesen Vektor für spätere Entschlüsselung speichern
$filter->setVector('myvector');
// $filter->getVector();

$encrypted = $filter->filter('text_to_be_encoded');
print $encrypted;

// Für Entschlüsselung siehe den Decrypt Filter
]]></programlisting>
    </sect3>

    <sect3 id="zend.filter.set.encrypt.openssl">
        <title>Verschlüsselung mit OpenSSL</title>

        <para>
            Wenn man die <classname>OpenSSL</classname> Erweiterung installiert hat, kann man den
            <classname>OpenSSL</classname> Adapter verwenden. Dieser Adapter unterstützt bei der
            Instanziierung die folgenden Optionen:
        </para>

        <itemizedlist>
            <listitem>
                <para>
                    <emphasis>public</emphasis>: Der öffentliche Schlüssel des Benutzer dem man
                    verschlüsselte Inhalte zur Verfügung stellen will. Man kann mehrere öffentliche
                    Schlüssel angeben indem man ein Array verwendet. Man kann entweder den Pfad und
                    den Dateinamen der Schlüsseldatei angeben, oder nur den Inhalt der Schlüseldatei
                    selbst.
                </para>
            </listitem>

            <listitem>
                <para>
                    <emphasis>private</emphasis>: Der eigene private Schlüssel der für die
                    Verschlüsselung des Inhalts verwendet wird. Auch der private Schlüssel kann
                    entweder ein Dateiname mit Pfad zur Schlüsseldatei sein, oder nur der Inhalt der
                    Schlüsseldatei selbst.
                </para>
            </listitem>

            <listitem>
                <para>
                    <emphasis>compression</emphasis>: Ob der verschlüsselte Wert komprimiert werden
                    soll. Standardmäßig wird nicht komprimiert.
                </para>
            </listitem>

            <listitem>
                <para>
                    <emphasis>package</emphasis>: Ob der Umschlagschlüssel mit dem verschlüsselten
                    Wert gepackt werden soll. Der Standardwert ist <constant>FALSE</constant>.
                </para>
            </listitem>
        </itemizedlist>

        <para>
            Man kann öffentliche Schlüssel auch im Nachhinein mit den Methoden
            <methodname>getPublicKey()</methodname> und <methodname>setPublicKey()</methodname>
            erhalten und setzen. Auch der private Schlüssel kann mit den entsprechenden Methoden
            <methodname>getPrivateKey()</methodname> und <methodname>setPrivateKey()</methodname>
            geholt und gesetzt werden.
        </para>

        <programlisting language="php"><![CDATA[
// Verwende openssl und gib einen privaten Schlüssel an
$filter = new Zend_Filter_Encrypt(array(
    'adapter' => 'openssl',
    'private' => '/path/to/mykey/private.pem'
));

// natürlich kann man die öffentlichen Schlüssel auch
// bei der Instanziierung angeben
$filter->setPublicKey(array(
    '/public/key/path/first.pem',
    '/public/key/path/second.pem'
));
]]></programlisting>

        <note>
            <para>
                Es ist zu beachten das der <classname>OpenSSL</classname> Adapter nicht
                funktionieren wird wenn keine gültigen Schlüsseln angegeben werden.
            </para>
        </note>

        <para>
            Wenn man auch die Schlüssel selbst verschlüsseln will, muß man eine Passphrase mit der
            <methodname>setPassphrase()</methodname> Methode angeben. Wenn man Inhalte
            entschlüsseln will, die mit einer Passphrase verschlüsselt wurden, muß man nicht nur
            den öffentlichen Schlüssel, sondern auch die Passphrase um den verschlüsselten
            Schlüssel zu entschlüsseln.
        </para>

        <programlisting language="php"><![CDATA[
// Verwende openssl und gib einen privaten Schlüssel an
$filter = new Zend_Filter_Encrypt(array(
    'adapter' => 'openssl',
    'private' => '/path/to/mykey/private.pem'
));

// Natürlich kann man die öffentlichen Schlüssel
// auch bei der Instanziierung angeben
$filter->setPublicKey(array(
    '/public/key/path/first.pem',
    '/public/key/path/second.pem'
));
$filter->setPassphrase('mypassphrase');
]]></programlisting>

        <para>
            Zum Schluß muß man, wenn OpenSSL verwendet wird, dem Empfänger den verschlüsselten
            Inhalt, die Passphrase, wenn eine angegeben wurde, und den Umschlagschlüssel für die
            Entschlüsselung angeben.
        </para>

        <para>
            Das bedeutet, das man die Umschlagschlüssel nach der Verschlüsselung mit der
            <methodname>getEnvelopeKey()</methodname> Methode holen muß.
        </para>

        <para>
            Unser komplettes Beispiel für die Verschlüsselung von Inhalten mit
            <classname>OpenSSL</classname> schaut wie folgt aus.
        </para>

        <programlisting language="php"><![CDATA[
// Verwende openssl und gib einen privaten Schlüssel an
$filter = new Zend_Filter_Encrypt(array(
    'adapter' => 'openssl',
    'private' => '/path/to/mykey/private.pem'
));

// natürlich kann man die öffentlichen Schlüssel
// auch bei der Instaiziierung angeben
$filter->setPublicKey(array(
    '/public/key/path/first.pem',
    '/public/key/path/second.pem'
));
$filter->setPassphrase('mypassphrase');

$encrypted = $filter->filter('text_to_be_encoded');
$envelope  = $filter->getEnvelopeKey();
print $encrypted;

// Für die Entschlüsselung siehe beim Decrypt Filter
]]></programlisting>

        <sect4 id="zend.filter.set.encrypt.openssl.simplified">
            <title>Vereinfachte Verwendung mit Openssl</title>

            <para>
                Wie vorher zu sehen war, muss man den Umschlagschlüssel holen um in der Lage zu sein
                den vorher verschlüsselten Wert wieder zu entschlüsseln. Das kann sehr frustrierend
                sein wenn man mit mehreren Werten arbeitet.
            </para>

            <para>
                Für eine vereinfachte Verwendung kann man die <property>package</property> Option
                auf <constant>TRUE</constant> setzen. Der Standardwert ist
                <constant>FALSE</constant>.
            </para>

            <programlisting language="php"><![CDATA[
// Verwende openssl und gib einen privaten Schlüssel an
$filter = new Zend_Filter_Encrypt(array(
    'adapter' => 'openssl',
    'private' => '/path/to/mykey/private.pem',
    'public'  => '/public/key/path/public.pem',
    'package' => true
));

$encrypted = $filter->filter('text_to_be_encoded');
print $encrypted;

// Für die Entschlüsselung siehe beim Decrypt Filter
]]></programlisting>

            <para>
                Jetzt enthält der zurückgegebene Wert sowohl den verschlüsselten Wert als auch den
                Umschlagschlüssel. Man muss diesen also nicht mehr nach der Verschlüsselung holen.
                Aber, und das ist der negative Aspekt dieses Features, der verschlüsselte Wert kann
                jetzt nur mehr entschlüsselt werden indem man
                <classname>Zend_Filter_Encrypt</classname> verwendet.
            </para>
        </sect4>

        <sect4 id="zend.filter.set.encrypt.openssl.compressed">
            <title>Komprimieren des Inhalts</title>

            <para>
                Basierend auf dem originalen Wert, kann der verschlüsselte Wert ein sehr langer
                String sein. Um den Wert zu reduzieren erlaubt
                <classname>Zend_Filter_Encrypt</classname> die Verwendung von Kompression.
            </para>

            <para>
                Die <property>compression</property> Option kann entweder auf den Namen eines
                Komprimierungsadapters gesetzt werden, oder auf ein Array welches alle gewünschten
                Optionen für den Komprimierungsadapter setzt.
            </para>

            <programlisting language="php"><![CDATA[
// Verwende nur den grundsätzlichen Komprimierungsadapter
$filter1 = new Zend_Filter_Encrypt(array(
    'adapter'     => 'openssl',
    'private'     => '/path/to/mykey/private.pem',
    'public'      => '/public/key/path/public.pem',
    'package'     => true,
    'compression' => 'bz2'
));

// Verwende den Basis Komprimierungsadapter
$filter2 = new Zend_Filter_Encrypt(array(
    'adapter'     => 'openssl',
    'private'     => '/path/to/mykey/private.pem',
    'public'      => '/public/key/path/public.pem',
    'package'     => true,
    'compression' => array('adapter' => 'zip', 'target' => '\usr\tmp\tmp.zip')
));
]]></programlisting>

            <note>
                <title>Entschlüsselung mit den selben Werten</title>

                <para>
                    Wenn man einen Wert entschlüsseln will welcher zusätzlich komprimiert wurde,
                    dann muss man die selben Komprimierungseinstellungen für die Entschlüsselung
                    verwenden wie bei der Verschlüsselung. Andernfalls wird die Entschlüsselung
                    fehlschlagen.
                </para>
            </note>
        </sect4>
    </sect3>
</sect2>
