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

    <para>
        These filters allow to encrypt and decrypt any given string. Therefor they make use of
        Adapters. Actually there are adapters for the <classname>Mcrypt</classname> and
        <classname>OpenSSL</classname> extensions from <acronym>PHP</acronym>.
    </para>

    <sect3 id="zend.filter.set.encrypt.options">
        <title>Supported options for Zend_Filter_Encrypt and Zend_Filter_Decrypt</title>

        <para>
            The following options are supported for <classname>Zend_Filter_Encrypt</classname> and
            <classname>Zend_Filter_Decrypt</classname>:
        </para>

        <itemizedlist>
            <listitem>
                <para>
                    <emphasis><property>adapter</property></emphasis>: This sets the encryption
                    adapter which should be used
                </para>
            </listitem>

            <listitem>
                <para>
                    <emphasis><property>algorithm</property></emphasis>: Only
                    <classname>MCrypt</classname>. The algorithm which has to be used. It should be
                    one of the algorithm ciphers which can be found under
                    <ulink url="http://php.net/mcrypt">PHP's mcrypt ciphers</ulink>. If not set it
                    defaults to <property>blowfish</property>.
                </para>
            </listitem>

            <listitem>
                <para>
                    <emphasis><property>algorithm_directory</property></emphasis>: Only
                    <classname>MCrypt</classname>. The directory where the algorithm can
                    be found. If not set it defaults to the path set within the mcrypt extension.
                </para>
            </listitem>

            <listitem>
                <para>
                    <emphasis><property>compression</property></emphasis>: If the encrypted value
                    should be compressed. Default is no compression.
                </para>
            </listitem>

            <listitem>
                <para>
                    <emphasis><property>envelope</property></emphasis>: Only
                    <classname>OpenSSL</classname>. The encrypted envelope key from the user who
                    encrypted the content. You can either provide the path and filename of the key
                    file, or just the content of the key file itself. When the
                    <property>package</property> option has been set, then you can omit this
                    parameter.
                </para>
            </listitem>

            <listitem>
                <para>
                    <emphasis><property>key</property></emphasis>: Only
                    <classname>MCrypt</classname>. The encryption key with which the input will be
                    encrypted. You need the same key for decryption.
                </para>
            </listitem>

            <listitem>
                <para>
                    <emphasis><property>mode</property></emphasis>: Only
                    <classname>MCrypt</classname>. The encryption mode which has to be used. It
                    should be one of the modes which can be found under
                    <ulink url="http://php.net/mcrypt">PHP's mcrypt modes</ulink>. If not set it
                    defaults to 'cbc'.
                </para>
            </listitem>

            <listitem>
                <para>
                    <emphasis><property>mode_directory</property></emphasis>: Only
                    <classname>MCrypt</classname>. The directory where the mode can be found.
                    If not set it defaults to the path set within the <classname>Mcrypt</classname>
                    extension.
                </para>
            </listitem>

            <listitem>
                <para>
                    <emphasis><property>package</property></emphasis>: Only
                    <classname>OpenSSL</classname>. If the envelope key should be packed with the
                    encrypted value. Default is <constant>FALSE</constant>.
                </para>
            </listitem>

            <listitem>
                <para>
                    <emphasis><property>private</property></emphasis>: Only
                    <classname>OpenSSL</classname>. Your private key which will be used for
                    encrypting the content. Also the private key can be either a filename with path
                    of the key file, or just the content of the key file itself.
                </para>
            </listitem>

            <listitem>
                <para>
                    <emphasis><property>public</property></emphasis>: Only
                    <classname>OpenSSL</classname>. The public key of the user whom you want to
                    provide the encrpted content. You can give multiple public keys by using an
                    array. You can eigther provide the path and filename of the key file, or just
                    the content of the key file itself.
                </para>
            </listitem>

            <listitem>
                <para>
                    <emphasis><property>salt</property></emphasis>: Only
                    <classname>MCrypt</classname>. If the key should be used as salt value. The key
                    used for encryption will then itself also be encrypted. Default is
                    <constant>FALSE</constant>.
                </para>
            </listitem>

            <listitem>
                <para>
                    <emphasis><property>vector</property></emphasis>: Only
                    <classname>MCrypt</classname>. The initialization vector which shall be used. If
                    not set it will be a random vector.
                </para>
            </listitem>
        </itemizedlist>
    </sect3>

    <sect3 id="zend.filter.set.encrypt.adapterusage">
        <title>Adapter usage</title>

        <para>
            As these two encryption methodologies work completely different, also the usage of the
            adapters differ. You have to select the adapter you want to use when initiating the
            filter.
        </para>

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

// Use the OpenSSL adapter
$filter2 = new Zend_Filter_Encrypt(array('adapter' => 'openssl'));
]]></programlisting>

        <para>
            To set another adapter you can also use <methodname>setAdapter()</methodname>, and the
            <methodname>getAdapter()</methodname> method to receive the actual set adapter.
        </para>

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

        <note>
            <para>
                When you do not supply the <property>adapter</property> option or do not use
                <methodname>setAdapter()</methodname>, then the <classname>Mcrypt</classname>
                adapter will be used per default.
            </para>
        </note>
    </sect3>

    <sect3 id="zend.filter.set.encrypt.mcrypt">
        <title>Encryption with Mcrypt</title>

        <para>
            When you have installed the <classname>Mcrypt</classname> extension you can use the
            <classname>Mcrypt</classname> adapter. If you provide a string instead of an array of
            options, this string will be used as key.
        </para>

        <para>
            You can get and set the encryption values also afterwards with the
            <methodname>getEncryption()</methodname> and <methodname>setEncryption()</methodname>
            methods.
        </para>

        <note>
            <para>
                Note that you will get an exception if the mcrypt extension is not available in your
                environment.
            </para>
        </note>

        <note>
            <para>
                You should also note that all settings which be checked when you create the instance
                or when you call <methodname>setEncryption()</methodname>. If mcrypt detects problem
                with your settings an exception will be thrown.
            </para>
        </note>

        <para>
            You can get or set the encryption vector by calling <methodname>getVector()</methodname>
            and <methodname>setVector()</methodname>. A given string will be truncated or padded to
            the needed vector size of the used algorithm.
        </para>

        <note>
            <para>
                Note that when you are not using an own vector, you must get the vector and store
                it. Otherwise you will not be able to decode the encoded string.
            </para>
        </note>

        <programlisting language="php"><![CDATA[
// Use the default blowfish settings
$filter = new Zend_Filter_Encrypt('myencryptionkey');

// Set a own vector, otherwise you must call getVector()
// and store this vector for later decryption
$filter->setVector('myvector');
// $filter->getVector();

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

// For decryption look at the Decrypt filter
]]></programlisting>
    </sect3>

    <sect3 id="zend.filter.set.encrypt.mcryptdecrypt">
        <title>Decryption with Mcrypt</title>

        <para>
            For decrypting content which was previously encrypted with <classname>Mcrypt</classname>
            you need to have the options with which the encryption has been called.
        </para>

        <para>
            There is one eminent difference for you. When you did not provide a vector at
            encryption you need to get it after you encrypted the content by using the
            <methodname>getVector()</methodname> method on the encryption filter. Without the
            correct vector you will not be able to decrypt the content.
        </para>

        <para>
            As soon as you have provided all options decryption is as simple as encryption.
        </para>

        <programlisting language="php"><![CDATA[
// Use the default blowfish settings
$filter = new Zend_Filter_Decrypt('myencryptionkey');

// Set the vector with which the content was encrypted
$filter->setVector('myvector');

$decrypted = $filter->filter('encoded_text_normally_unreadable');
print $decrypted;
]]></programlisting>

        <note>
            <para>
                Note that you will get an exception if the mcrypt extension is not available in your
                environment.
            </para>
        </note>

        <note>
            <para>
                You should also note that all settings which be checked when you create the instance
                or when you call <methodname>setEncryption()</methodname>. If mcrypt detects problem
                with your settings an exception will be thrown.
            </para>
        </note>
    </sect3>

    <sect3 id="zend.filter.set.encrypt.openssl">
        <title>Encryption with OpenSSL</title>

        <para>
            When you have installed the <classname>OpenSSL</classname> extension you can use the
            <classname>OpenSSL</classname> adapter. You can get or set the public keys also
            afterwards with the <methodname>getPublicKey()</methodname> and
            <methodname>setPublicKey()</methodname> methods. The private key can also be get and set
            with the related <methodname>getPrivateKey()</methodname> and
            <methodname>setPrivateKey()</methodname> methods.
        </para>

        <programlisting language="php"><![CDATA[
// Use openssl and provide a private key
$filter = new Zend_Filter_Encrypt(array(
    'adapter' => 'openssl',
    'private' => '/path/to/mykey/private.pem'
));

// of course you can also give the public keys at initiation
$filter->setPublicKey(array(
    '/public/key/path/first.pem',
    '/public/key/path/second.pem'
));
]]></programlisting>

        <note>
            <para>
                Note that the <classname>OpenSSL</classname> adapter will not work when you do not
                provide valid keys.
            </para>
        </note>

        <para>
            When you want to encode also the keys, then you have to provide a passphrase with the
            <methodname>setPassphrase()</methodname> method. When you want to decode content which
            was encoded with a passphrase you will not only need the public key, but also the
            passphrase to decode the encrypted key.
        </para>

        <programlisting language="php"><![CDATA[
// Use openssl and provide a private key
$filter = new Zend_Filter_Encrypt(array(
    'adapter' => 'openssl',
    'private' => '/path/to/mykey/private.pem'
));

// of course you can also give the public keys at initiation
$filter->setPublicKey(array(
    '/public/key/path/first.pem',
    '/public/key/path/second.pem'
));
$filter->setPassphrase('mypassphrase');
]]></programlisting>

        <para>
            At last, when you use OpenSSL you need to give the receiver the encrypted content, the
            passphrase when have provided one, and the envelope keys for decryption.
        </para>

        <para>
            This means for you, that you have to get the envelope keys after the encryption with the
            <methodname>getEnvelopeKey()</methodname> method.
        </para>

        <para>
            So our complete example for encrypting content with <classname>OpenSSL</classname> look
            like this.
        </para>

        <programlisting language="php"><![CDATA[
// Use openssl and provide a private key
$filter = new Zend_Filter_Encrypt(array(
    'adapter' => 'openssl',
    'private' => '/path/to/mykey/private.pem'
));

// of course you can also give the public keys at initiation
$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;

// For decryption look at the Decrypt filter
]]></programlisting>

        <sect4 id="zend.filter.set.encrypt.openssl.simplified">
            <title>Simplified usage with Openssl</title>

            <para>
                As seen before, you need to get the envelope key to be able to decrypt the previous
                encrypted value. This can be very annoying when you work with multiple values.
            </para>

            <para>
                To have a simplified usage you can set the <property>package</property> option to
                <constant>TRUE</constant>. The default value is <constant>FALSE</constant>.
            </para>

            <programlisting language="php"><![CDATA[
// Use openssl and provide a private key
$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;

// For decryption look at the Decrypt filter
]]></programlisting>

            <para>
                Now the returned value contains the encrypted value and the envelope. You don't
                need to get them after the compression. But, and this is the negative aspect of
                this feature, the encrypted value can now only be decrypted by using
                <classname>Zend_Filter_Encrypt</classname>.
            </para>
        </sect4>

        <sect4 id="zend.filter.set.encrypt.openssl.compressed">
            <title>Compressing the content</title>

            <para>
                Based on the original value, the encrypted value can be a very large string. To
                reduce the value <classname>Zend_Filter_Encrypt</classname> allows the usage of
                compression.
            </para>

            <para>
                The <property>compression</property> option can eighter be set to the name of a
                compression adapter, or to an array which sets all wished options for the
                compression adapter.
            </para>

            <programlisting language="php"><![CDATA[
// Use basic compression adapter
$filter1 = new Zend_Filter_Encrypt(array(
    'adapter'     => 'openssl',
    'private'     => '/path/to/mykey/private.pem',
    'public'      => '/public/key/path/public.pem',
    'package'     => true,
    'compression' => 'bz2'
));

// Use basic compression adapter
$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>Decryption with same settings</title>

                <para>
                    When you want to decrypt a value which is additionally compressed, then you
                    need to set the same compression settings for decryption as for encryption.
                    Otherwise the decryption will fail.
                </para>
            </note>
        </sect4>
    </sect3>

    <sect3 id="zend.filter.set.encrypt.openssldecrypt">
        <title>Decryption with OpenSSL</title>

        <para>
            Decryption with <classname>OpenSSL</classname> is as simple as encryption. But you need
            to have all data from the person who encrypted the content. See the following example:
        </para>

        <programlisting language="php"><![CDATA[
// Use openssl and provide a private key
$filter = new Zend_Filter_Decrypt(array(
    'adapter' => 'openssl',
    'private' => '/path/to/mykey/private.pem'
));

// of course you can also give the envelope keys at initiation
$filter->setEnvelopeKey(array(
    '/key/from/encoder/first.pem',
    '/key/from/encoder/second.pem'
));
]]></programlisting>

        <note>
            <para>
                Note that the <classname>OpenSSL</classname> adapter will not work when you do not
                provide valid keys.
            </para>
        </note>

        <para>
            Optionally it could be necessary to provide the passphrase for decrypting the keys
            themself by using the <methodname>setPassphrase()</methodname> method.
        </para>

        <programlisting language="php"><![CDATA[
// Use openssl and provide a private key
$filter = new Zend_Filter_Decrypt(array(
    'adapter' => 'openssl',
    'private' => '/path/to/mykey/private.pem'
));

// of course you can also give the envelope keys at initiation
$filter->setEnvelopeKey(array(
    '/key/from/encoder/first.pem',
    '/key/from/encoder/second.pem'
));
$filter->setPassphrase('mypassphrase');
]]></programlisting>

        <para>
            At last, decode the content. Our complete example for decrypting the previously
            encrypted content looks like this.
        </para>

        <programlisting language="php"><![CDATA[
// Use openssl and provide a private key
$filter = new Zend_Filter_Decrypt(array(
    'adapter' => 'openssl',
    'private' => '/path/to/mykey/private.pem'
));

// of course you can also give the envelope keys at initiation
$filter->setEnvelopeKey(array(
    '/key/from/encoder/first.pem',
    '/key/from/encoder/second.pem'
));
$filter->setPassphrase('mypassphrase');

$decrypted = $filter->filter('encoded_text_normally_unreadable');
print $decrypted;
]]></programlisting>
    </sect3>
</sect2>
<!--
vim:se ts=4 sw=4 et:
-->