Browse Source

[GENERIC] Zend_Filter_Compress:

- added 'package' option to Openssl adapter
- added 'compression' option to Openssl adapter
- added 'compression' option to Mcrypt adapter

git-svn-id: http://framework.zend.com/svn/framework/standard/trunk@21212 44c647ce-9c0f-0410-b52a-842ac1e357ba
thomas 16 years ago
parent
commit
970c6395f9

+ 10 - 1
documentation/manual/en/module_specs/Zend_Filter-Decryption.xml

@@ -86,7 +86,16 @@ print $decrypted;
                 <para>
                     <emphasis>envelope</emphasis>: 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.
+                    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>package</emphasis>: If the envelope key has been packed with the
+                    encrypted value. Defaults to <constant>FALSE</constant>.
                 </para>
             </listitem>
         </itemizedlist>

+ 105 - 0
documentation/manual/en/module_specs/Zend_Filter-Encryption.xml

@@ -102,6 +102,15 @@ $filter->setAdapter('openssl');
                     <constant>FALSE</constant>.
                 </para>
             </listitem>
+
+            <listitem>
+                <para>
+                    <emphasis>compression</emphasis>: If the encrypted value should be compressed.
+                    Default is no compression. For details take a look into <link
+                        linkend="zend.filter.set.encrypt.openssl.compressed">compression for
+                        Openssl</link>.
+                </para>
+            </listitem>
         </itemizedlist>
 
         <para>
@@ -183,6 +192,20 @@ print $encrypted;
                     file, or just the content of the key file itself.
                 </para>
             </listitem>
+
+            <listitem>
+                <para>
+                    <emphasis>compression</emphasis>: If the encrypted value should be compressed.
+                    Default is no compression.
+                </para>
+            </listitem>
+
+            <listitem>
+                <para>
+                    <emphasis>package</emphasis>: If the envelope key should be packed with the
+                    encrypted value. Default is <constant>FALSE</constant>.
+                </para>
+            </listitem>
         </itemizedlist>
 
         <para>
@@ -270,6 +293,88 @@ 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>
 </sect2>
 <!--

+ 62 - 10
library/Zend/Filter/Encrypt/Mcrypt.php

@@ -54,8 +54,15 @@ class Zend_Filter_Encrypt_Mcrypt implements Zend_Filter_Encrypt_Interface
         'salt'                => false
     );
 
+    /**
+     * Internal compression
+     *
+     * @var array
+     */
+    protected $_compression;
+
     protected static $_srandCalled = false;
-    
+
     /**
      * Class constructor
      *
@@ -77,6 +84,11 @@ class Zend_Filter_Encrypt_Mcrypt implements Zend_Filter_Encrypt_Interface
             throw new Zend_Filter_Exception('Invalid options argument provided to filter');
         }
 
+        if (array_key_exists('compression', $options)) {
+            $this->setCompression($options['compression']);
+            unset($options['compress']);
+        }
+
         $this->setEncryption($options);
     }
 
@@ -181,15 +193,48 @@ class Zend_Filter_Encrypt_Mcrypt implements Zend_Filter_Encrypt_Interface
     }
 
     /**
+     * Returns the compression
+     *
+     * @return array
+     */
+    public function getCompression()
+    {
+        return $this->_compression;
+    }
+
+    /**
+     * Sets a internal compression for values to encrypt
+     *
+     * @param string|array $compression
+     * @return Zend_Filter_Encrypt_Mcrypt
+     */
+    public function setCompression($compression)
+    {
+        if (is_string($this->_compression)) {
+            $compression = array('adapter' => $compression);
+        }
+
+        $this->_compression = $compression;
+        return $this;
+    }
+
+    /**
      * Defined by Zend_Filter_Interface
      *
-     * Encrypts the file $value with the defined settings
+     * Encrypts $value with the defined settings
      *
-     * @param  string $value Full path of file to change
-     * @return string The filename which has been set, or false when there were errors
+     * @param  string $value The content to encrypt
+     * @return string The encrypted content
      */
     public function encrypt($value)
     {
+        // compress prior to encryption
+        if (!empty($this->_compression)) {
+            require_once 'Zend/Filter/Compress.php';
+            $compress = new Zend_Filter_Compress($this->_compression);
+            $value    = $compress->filter($value);
+        }
+
         $cipher  = $this->_openCipher();
         $this->_initCipher($cipher);
         $encrypted = mcrypt_generic($cipher, $value);
@@ -202,10 +247,10 @@ class Zend_Filter_Encrypt_Mcrypt implements Zend_Filter_Encrypt_Interface
     /**
      * Defined by Zend_Filter_Interface
      *
-     * Decrypts the file $value with the defined settings
+     * Decrypts $value with the defined settings
      *
-     * @param  string $value Full path of file to change
-     * @return string The filename which has been set, or false when there were errors
+     * @param  string $value Content to decrypt
+     * @return string The decrypted content
      */
     public function decrypt($value)
     {
@@ -215,6 +260,13 @@ class Zend_Filter_Encrypt_Mcrypt implements Zend_Filter_Encrypt_Interface
         mcrypt_generic_deinit($cipher);
         $this->_closeCipher($cipher);
 
+        // decompress after decryption
+        if (!empty($this->_compression)) {
+            require_once 'Zend/Filter/Decompress.php';
+            $decompress = new Zend_Filter_Decompress($this->_compression);
+            $decrypted  = $decompress->filter($decrypted);
+        }
+
         return $decrypted;
     }
 
@@ -292,10 +344,10 @@ class Zend_Filter_Encrypt_Mcrypt implements Zend_Filter_Encrypt_Interface
 
         return $this;
     }
-    
+
     /**
      * _srand() interception
-     * 
+     *
      * @see ZF-8742
      */
     protected function _srand()
@@ -303,7 +355,7 @@ class Zend_Filter_Encrypt_Mcrypt implements Zend_Filter_Encrypt_Interface
         if (version_compare(PHP_VERSION, '5.3.0', '>=')) {
             return;
         }
-        
+
         if (!self::$_srandCalled) {
             srand((double) microtime() * 1000000);
             self::$_srandCalled = true;

+ 152 - 13
library/Zend/Filter/Encrypt/Openssl.php

@@ -56,12 +56,28 @@ class Zend_Filter_Encrypt_Openssl implements Zend_Filter_Encrypt_Interface
     protected $_passphrase;
 
     /**
+     * Internal compression
+     *
+     * @var array
+     */
+    protected $_compression;
+
+    /**
+     * Internal create package
+     *
+     * @var boolean
+     */
+    protected $_package = false;
+
+    /**
      * Class constructor
      * Available options
-     *   'public'     => public key
-     *   'private'    => private key
-     *   'envelope'   => envelope key
-     *   'passphrase' => passphrase
+     *   'public'      => public key
+     *   'private'     => private key
+     *   'envelope'    => envelope key
+     *   'passphrase'  => passphrase
+     *   'compression' => compress value with this compression adapter
+     *   'package'     => pack envelope keys into encrypted string, simplifies decryption
      *
      * @param string|array $options Options for this adapter
      */
@@ -85,6 +101,16 @@ class Zend_Filter_Encrypt_Openssl implements Zend_Filter_Encrypt_Interface
             unset($options['passphrase']);
         }
 
+        if (array_key_exists('compression', $options)) {
+            $this->setCompression($options['compression']);
+            unset($options['compress']);
+        }
+
+        if (array_key_exists('package', $options)) {
+            $this->setPackage($options['package']);
+            unset($options['package']);
+        }
+
         $this->_setKeys($options);
     }
 
@@ -150,7 +176,8 @@ class Zend_Filter_Encrypt_Openssl implements Zend_Filter_Encrypt_Interface
      */
     public function getPublicKey()
     {
-        return $this->_keys['public'];
+        $key = $this->_keys['public'];
+        return $key;
     }
 
     /**
@@ -182,7 +209,8 @@ class Zend_Filter_Encrypt_Openssl implements Zend_Filter_Encrypt_Interface
      */
     public function getPrivateKey()
     {
-        return $this->_keys['private'];
+        $key = $this->_keys['private'];
+        return $key;
     }
 
     /**
@@ -219,7 +247,8 @@ class Zend_Filter_Encrypt_Openssl implements Zend_Filter_Encrypt_Interface
      */
     public function getEnvelopeKey()
     {
-        return $this->_keys['envelope'];
+        $key = $this->_keys['envelope'];
+        return $key;
     }
 
     /**
@@ -267,7 +296,55 @@ class Zend_Filter_Encrypt_Openssl implements Zend_Filter_Encrypt_Interface
     }
 
     /**
-     * Encrypts the file $value with the defined settings
+     * Returns the compression
+     *
+     * @return array
+     */
+    public function getCompression()
+    {
+        return $this->_compression;
+    }
+
+    /**
+     * Sets a internal compression for values to encrypt
+     *
+     * @param string|array $compression
+     * @return Zend_Filter_Encrypt_Openssl
+     */
+    public function setCompression($compression)
+    {
+        if (is_string($this->_compression)) {
+            $compression = array('adapter' => $compression);
+        }
+
+        $this->_compression = $compression;
+        return $this;
+    }
+
+    /**
+     * Returns if header should be packaged
+     *
+     * @return boolean
+     */
+    public function getPackage()
+    {
+        return $this->_package;
+    }
+
+    /**
+     * Sets if the envelope keys should be included in the encrypted value
+     *
+     * @param boolean $package
+     * @return Zend_Filter_Encrypt_Openssl
+     */
+    public function setPackage($package)
+    {
+        $this->_package = (boolean) $package;
+        return $this;
+    }
+
+    /**
+     * Encrypts $value with the defined settings
      * Note that you also need the "encrypted" keys to be able to decrypt
      *
      * @param  string $value Content to encrypt
@@ -284,8 +361,27 @@ class Zend_Filter_Encrypt_Openssl implements Zend_Filter_Encrypt_Interface
             throw new Zend_Filter_Exception('Openssl can not encrypt without public keys');
         }
 
+        $keys         = array();
+        $fingerprints = array();
+        $count        = -1;
         foreach($this->_keys['public'] as $key => $cert) {
             $keys[$key] = openssl_pkey_get_public($cert);
+            if ($this->_package) {
+                $details = openssl_pkey_get_details($keys[$key]);
+                if ($details === false) {
+                    $details = array('key' => 'ZendFramework');
+                }
+
+                ++$count;
+                $fingerprints[$count] = md5($details['key']);
+            }
+        }
+
+        // compress prior to encryption
+        if (!empty($this->_compression)) {
+            require_once 'Zend/Filter/Compress.php';
+            $compress = new Zend_Filter_Compress($this->_compression);
+            $value    = $compress->filter($value);
         }
 
         $crypt  = openssl_seal($value, $encrypted, $encryptedkeys, $keys);
@@ -295,17 +391,28 @@ class Zend_Filter_Encrypt_Openssl implements Zend_Filter_Encrypt_Interface
 
         if ($crypt === false) {
             require_once 'Zend/Filter/Exception.php';
-            throw new Zend_Filter_Exception('Openssl was not able to encrypt you content with the given options');
+            throw new Zend_Filter_Exception('Openssl was not able to encrypt your content with the given options');
         }
 
         $this->_keys['envelope'] = $encryptedkeys;
+
+        // Pack data and envelope keys into single string
+        if ($this->_package) {
+            $header = pack('n', count($this->_keys['envelope']));
+            foreach($this->_keys['envelope'] as $key => $envKey) {
+                $header .= pack('H32n', $fingerprints[$key], strlen($envKey)) . $envKey;
+            }
+
+            $encrypted = $header . $encrypted;
+        }
+
         return $encrypted;
     }
 
     /**
      * Defined by Zend_Filter_Interface
      *
-     * Decrypts the file $value with the defined settings
+     * Decrypts $value with the defined settings
      *
      * @param  string $value Content to decrypt
      * @return string The decrypted content
@@ -318,18 +425,43 @@ class Zend_Filter_Encrypt_Openssl implements Zend_Filter_Encrypt_Interface
 
         if (count($this->_keys['private']) !== 1) {
             require_once 'Zend/Filter/Exception.php';
-            throw new Zend_Filter_Exception('Openssl can only decrypt with one private key');
+            throw new Zend_Filter_Exception('Please give a private key for decryption with Openssl');
         }
 
-        if (empty($envelope)) {
+        if (!$this->_package && empty($envelope)) {
             require_once 'Zend/Filter/Exception.php';
-            throw new Zend_Filter_Exception('Openssl can only decrypt with one envelope key');
+            throw new Zend_Filter_Exception('Please give a envelope key for decryption with Openssl');
         }
 
         foreach($this->_keys['private'] as $key => $cert) {
             $keys = openssl_pkey_get_private($cert, $this->getPassphrase());
         }
 
+        if ($this->_package) {
+            $details = openssl_pkey_get_details($keys);
+            if ($details !== false) {
+                $fingerprint = md5($details['key']);
+            } else {
+                $fingerprint = md5("ZendFramework");
+            }
+
+            $count = unpack('ncount', $value);
+            $count = $count['count'];
+            $length  = 2;
+            for($i = $count; $i > 0; --$i) {
+                $header = unpack('H32print/nsize', substr($value, $length, 18));
+                $length  += 18;
+                if ($header['print'] == $fingerprint) {
+                    $envelope = substr($value, $length, $header['size']);
+                }
+
+                $length += $header['size'];
+            }
+
+            // remainder of string is the value to decrypt
+            $value = substr($value, $length);
+        }
+
         $crypt  = openssl_open($value, $decrypted, $envelope, $keys);
         openssl_free_key($keys);
 
@@ -338,6 +470,13 @@ class Zend_Filter_Encrypt_Openssl implements Zend_Filter_Encrypt_Interface
             throw new Zend_Filter_Exception('Openssl was not able to decrypt you content with the given options');
         }
 
+        // decompress after decryption
+        if (!empty($this->_compression)) {
+            require_once 'Zend/Filter/Decompress.php';
+            $decompress = new Zend_Filter_Decompress($this->_compression);
+            $decrypted  = $decompress->filter($decrypted);
+        }
+
         return $decrypted;
     }
 

+ 22 - 36
tests/Zend/Filter/Encrypt/McryptTest.php

@@ -76,10 +76,6 @@ class Zend_Filter_Encrypt_McryptTest extends PHPUnit_Framework_TestCase
      */
     public function testGetSetVector()
     {
-        if (!extension_loaded('mcrypt')) {
-            $this->markTestSkipped('Mcrypt extension not installed');
-        }
-
         $filter = new Zend_Filter_Encrypt_Mcrypt(array('key' => 'testkey'));
         $filter->setVector('testvect');
         $this->assertEquals('testvect', $filter->getVector());
@@ -99,10 +95,6 @@ class Zend_Filter_Encrypt_McryptTest extends PHPUnit_Framework_TestCase
      */
     public function testDefaultEncryption()
     {
-        if (!extension_loaded('mcrypt')) {
-            $this->markTestSkipped('Mcrypt extension not installed');
-        }
-
         $filter = new Zend_Filter_Encrypt_Mcrypt(array('key' => 'testkey'));
         $filter->setVector('testvect');
         $this->assertEquals(
@@ -124,10 +116,6 @@ class Zend_Filter_Encrypt_McryptTest extends PHPUnit_Framework_TestCase
      */
     public function testGetSetEncryption()
     {
-        if (!extension_loaded('mcrypt')) {
-            $this->markTestSkipped('Mcrypt extension not installed');
-        }
-
         $filter = new Zend_Filter_Encrypt_Mcrypt(array('key' => 'testkey'));
         $filter->setVector('testvect');
         $filter->setEncryption(
@@ -152,10 +140,6 @@ class Zend_Filter_Encrypt_McryptTest extends PHPUnit_Framework_TestCase
      */
     public function testEncryptionWithDecryptionMcrypt()
     {
-        if (!extension_loaded('mcrypt')) {
-            $this->markTestSkipped('Mcrypt extension not installed');
-        }
-
         $filter = new Zend_Filter_Encrypt_Mcrypt(array('key' => 'testkey'));
         $filter->setVector('testvect');
         $output = $filter->encrypt('teststring');
@@ -171,10 +155,6 @@ class Zend_Filter_Encrypt_McryptTest extends PHPUnit_Framework_TestCase
      */
     public function testConstructionWithStringKey()
     {
-        if (!extension_loaded('mcrypt')) {
-            $this->markTestSkipped('Mcrypt extension not installed');
-        }
-
         $filter = new Zend_Filter_Encrypt_Mcrypt('testkey');
         $data = $filter->getEncryption();
         $this->assertEquals('testkey', $data['key']);
@@ -185,10 +165,6 @@ class Zend_Filter_Encrypt_McryptTest extends PHPUnit_Framework_TestCase
      */
     public function testConstructionWithInteger()
     {
-        if (!extension_loaded('mcrypt')) {
-            $this->markTestSkipped('Mcrypt extension not installed');
-        }
-
         try {
             $filter = new Zend_Filter_Encrypt_Mcrypt(1234);
             $this->fail();
@@ -202,10 +178,6 @@ class Zend_Filter_Encrypt_McryptTest extends PHPUnit_Framework_TestCase
      */
     public function testToString()
     {
-        if (!extension_loaded('mcrypt')) {
-            $this->markTestSkipped('Mcrypt extension not installed');
-        }
-
         $filter = new Zend_Filter_Encrypt_Mcrypt('testkey');
         $this->assertEquals('Mcrypt', $filter->toString());
     }
@@ -215,10 +187,6 @@ class Zend_Filter_Encrypt_McryptTest extends PHPUnit_Framework_TestCase
      */
     public function testSettingEncryptionOptions()
     {
-        if (!extension_loaded('mcrypt')) {
-            $this->markTestSkipped('Mcrypt extension not installed');
-        }
-
         $filter = new Zend_Filter_Encrypt_Mcrypt('testkey');
         $filter->setEncryption('newkey');
         $test = $filter->getEncryption();
@@ -251,11 +219,29 @@ class Zend_Filter_Encrypt_McryptTest extends PHPUnit_Framework_TestCase
      */
     public function testSettingEmptyVector()
     {
-        if (!extension_loaded('mcrypt')) {
-            $this->markTestSkipped('Mcrypt extension not installed');
-        }
-
         $filter = new Zend_Filter_Encrypt_Mcrypt('newkey');
         $filter->setVector();
     }
+
+    /**
+     * Ensures that the filter allows de/encryption with compression
+     *
+     * @return void
+     */
+    public function testEncryptionWithDecryptionAndCompressionMcrypt()
+    {
+        if (!extension_loaded('bz2')) {
+            $this->markTestSkipped('This adapter needs the bz2 extension');
+        }
+
+        $filter = new Zend_Filter_Encrypt_Mcrypt(array('key' => 'testkey'));
+        $filter->setVector('testvect');
+        $filter->setCompression('bz2');
+        $output = $filter->encrypt('teststring');
+
+        $this->assertNotEquals('teststring', $output);
+
+        $input = $filter->decrypt($output);
+        $this->assertEquals('teststring', trim($input));
+    }
 }

+ 55 - 2
tests/Zend/Filter/Encrypt/OpensslTest.php

@@ -208,7 +208,7 @@ d/fxzPfuO/bLpADozTAnYT9Hu3wPrQVLeAfCp0ojqH7DYg==
             $filter->decrypt('unknown');
             $this->fail();
         } catch (Zend_Filter_Exception $e) {
-            $this->assertContains('with one private key', $e->getMessage());
+            $this->assertContains('Please give a private key', $e->getMessage());
         }
 
         $filter->setPrivateKey(array('public' => dirname(__FILE__) . '/../_files/privatekey.pem'));
@@ -216,7 +216,7 @@ d/fxzPfuO/bLpADozTAnYT9Hu3wPrQVLeAfCp0ojqH7DYg==
             $filter->decrypt('unknown');
             $this->fail();
         } catch (Zend_Filter_Exception $e) {
-            $this->assertContains('with one envelope key', $e->getMessage());
+            $this->assertContains('Please give a envelope key', $e->getMessage());
         }
 
         $filter->setEnvelopeKey('unknown');
@@ -261,4 +261,57 @@ bK22CwD/l7SMBOz4M9XH0Jb0OhNxLza4XMDu0ANMIpnkn1KOcmQ4gB8fmAbBt';
         $this->assertFalse(empty($public));
         $this->assertEquals($passphrase, $filter->getPassphrase());
     }
+
+    /**
+     * Ensures that the filter allows de/encryption
+     *
+     * @return void
+     */
+    public function testEncryptionWithDecryptionWithPackagedKeys()
+    {
+        $filter = new Zend_Filter_Encrypt_Openssl();
+        $filter->setPublicKey(dirname(__FILE__) . '/../_files/publickey.pem');
+        $filter->setPackage(true);
+        $output = $filter->encrypt('teststring');
+        $this->assertNotEquals('teststring', $output);
+
+        $phrase = 'zPUp9mCzIrM7xQOEnPJZiDkBwPBV9UlITY0Xd3v4bfIwzJ12yPQCAkcR5BsePGVw
+RK6GS5RwXSLrJu9Qj8+fk0wPj6IPY5HvA9Dgwh+dptPlXppeBm3JZJ+92l0DqR2M
+ccL43V3Z4JN9OXRAfGWXyrBJNmwURkq7a2EyFElBBWK03OLYVMevQyRJcMKY0ai+
+tmnFUSkH2zwnkXQfPUxg9aV7TmGQv/3TkK1SziyDyNm7GwtyIlfcigCCRz3uc77U
+Izcez5wgmkpNElg/D7/VCd9E+grTfPYNmuTVccGOes+n8ISJJdW0vYX1xwWv5l
+bK22CwD/l7SMBOz4M9XH0Jb0OhNxLza4XMDu0ANMIpnkn1KOcmQ4gB8fmAbBt';
+        $filter->setPrivateKey(dirname(__FILE__) . '/../_files/privatekey.pem', $phrase);
+        $input = $filter->decrypt($output);
+        $this->assertEquals('teststring', trim($input));
+    }
+
+    /**
+     * Ensures that the filter allows de/encryption
+     *
+     * @return void
+     */
+    public function testEncryptionWithDecryptionAndCompressionWithPackagedKeys()
+    {
+        if (!extension_loaded('bz2')) {
+            $this->markTestSkipped('Bz2 extension for compression test needed');
+        }
+
+        $filter = new Zend_Filter_Encrypt_Openssl();
+        $filter->setPublicKey(dirname(__FILE__) . '/../_files/publickey.pem');
+        $filter->setPackage(true);
+        $filter->setCompression('bz2');
+        $output = $filter->encrypt('teststring');
+        $this->assertNotEquals('teststring', $output);
+
+        $phrase = 'zPUp9mCzIrM7xQOEnPJZiDkBwPBV9UlITY0Xd3v4bfIwzJ12yPQCAkcR5BsePGVw
+RK6GS5RwXSLrJu9Qj8+fk0wPj6IPY5HvA9Dgwh+dptPlXppeBm3JZJ+92l0DqR2M
+ccL43V3Z4JN9OXRAfGWXyrBJNmwURkq7a2EyFElBBWK03OLYVMevQyRJcMKY0ai+
+tmnFUSkH2zwnkXQfPUxg9aV7TmGQv/3TkK1SziyDyNm7GwtyIlfcigCCRz3uc77U
+Izcez5wgmkpNElg/D7/VCd9E+grTfPYNmuTVccGOes+n8ISJJdW0vYX1xwWv5l
+bK22CwD/l7SMBOz4M9XH0Jb0OhNxLza4XMDu0ANMIpnkn1KOcmQ4gB8fmAbBt';
+        $filter->setPrivateKey(dirname(__FILE__) . '/../_files/privatekey.pem', $phrase);
+        $input = $filter->decrypt($output);
+        $this->assertEquals('teststring', trim($input));
+    }
 }