# Encrypt 及び Decrypt

これらのフィルタにより、与えられた文字列を暗号化したり復号化できます。 したがって、それらはアダプタを利用します。 実際には、PHP 由来の `Mcrypt` および `OpenSSL` エクステンション用のアダプタを使用します。

## Zend_Filter_Encrypt および Zend_Filter_Decrypt でサポートされるオプション

`Zend_Filter_Encrypt` および `Zend_Filter_Decrypt` では、下記のオプションがサポートされます。

- adapter: 使用する暗号化アダプタを設定します。

- algorithm: `MCrypt` のみ。 使用するアルゴリズム PHP の mcrypt 暗号 であげられている暗号化アルゴリズムのいずれかでなければなりません。 省略した場合のデフォルトは blowfish です。

- algorithm_directory: `MCrypt` のみ。 アルゴリズムが存在するディレクトリ。 省略した場合のデフォルトは、mcrypt エクステンション内に設定されたパスです。

- compression: 暗号化した値を圧縮するかどうか。既定値は圧縮なし。

- envelope: `OpenSSL` のみ。 コンテンツを暗号化した人から受け取った、 暗号化されたエンベロープ鍵。 鍵ファイルのパスとファイル名を指定するか、 あるいは単に鍵ファイルの内容そのものを指定することもできます。 package オプションが設定された場合、 このパラメータは省略できます。

- key: `MCrypt` のみ。 暗号化用の鍵。 入力を暗号化する際に使用します。 復号する際にも同じ鍵が必要です。

- mode: `MCrypt` のみ。 使用する暗号化モード。 PHP の mcrypt 暗号 であげられているモードのいずれかでなければなりません。 省略した場合のデフォルトは 'cbc' です。

- mode_directory: `MCrypt` のみ。 モードが存在するディレクトリ。 省略した場合のデフォルトは、`Mcrypt` 拡張モジュールで設定されているパスです。

- package: `OpenSSL` のみ。 暗号化された値と一緒にエンベロープ鍵が梱包されるべきかどうか デフォルトは `FALSE` です。

- private: `OpenSSL` のみ。 コンテンツの暗号化に使用する、あなたの秘密鍵。 鍵ファイルのパスとファイル名を指定するか、 あるいは単に鍵ファイルの内容そのものを指定することもできます。

- public: `OpenSSL` のみ。 暗号化したコンテンツを渡したい相手の公開鍵。 複数の公開鍵を指定するには、配列を使用します。 鍵ファイルのパスとファイル名を指定するか、 あるいは単に鍵ファイルの内容そのものを指定することもできます。

- salt: `MCrypt` のみ。 キーを salt 値として使用するかどうか。 使用すると、暗号化に使用するキー自体も暗号化されます。 デフォルトは `FALSE` です。

- vector: `MCrypt` のみ。 使用する初期化ベクトル。 省略した場合はランダムなベクトルとなります。

## アダプタの使用法

これら 2 つの暗号化手法はまったく異なる方式なので、 アダプタの使用法もそれぞれ異なります。 フィルタを初期化する際に、どのアダプタを使うかを選ばなければなりません。

    // Mcrypt アダプタを使用します
    $filter1 = new Zend_Filter_Encrypt(array('adapter' => 'mcrypt'));

    // OpenSSL アダプタを使用します
    $filter2 = new Zend_Filter_Encrypt(array('adapter' => 'openssl'));

別のアダプタを設定するために `setAdapter()` を使用することもできます。また `getAdapter()` メソッドで、実際に設定されているアダプタを取得できます。

    // Mcrypt アダプタを使用します
    $filter = new Zend_Filter_Encrypt();
    $filter->setAdapter('openssl');

adapter オプションを指定しなかったり `setAdapter()` を使用しなかったりした場合は、デフォルトで `Mcrypt` アダプタを使用します。

## Mcrypt での暗号化

`Mcrypt` 拡張モジュールをインストールすると、 `Mcrypt` アダプタが使えるようになります。 もしオプション配列の代わりに文字列を与えると、 文字列がキーとして使われます。

初期化した後で暗号化の値を取得したり設定したりするには、それぞれ `getEncryption()` および `setEncryption()` メソッドを使用します。

mcrypt 拡張モジュールが使用できない場合は例外が発生することに注意しましょう。

また、インスタンス作成時あるいは `setEncryption()` をコールした際にすべての設定がチェックされることにも注意しましょう。 設定内容に問題があることを mcrypt が検知すると、例外がスローされます。

暗号化ベクトルの取得や設定には、それぞれ `getVector()` および `setVector()` を使用可能です。指定した文字列が、 そのアルゴリズムに必要なベクトルのサイズに応じて切り詰められたり伸ばされたりします。

自前のベクトル以外を使用する場合は、 そのベクトルを取得してどこかに保存しておかなければならないことに注意しましょう。 そうしないと、文字列が復号できなくなります。

    // デフォルト設定の blowfish を使用します
    $filter = new Zend_Filter_Encrypt('myencryptionkey');

    // 自前のベクトルを設定します。それ以外の場合は getVector()
    // をコールしてベクトルを保存しておかないと、後で復号できなくなります
    $filter->setVector('myvector');
    // $filter->getVector();

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

    // 復号の方法は Decrypt フィルタを参照ください

## Mcrypt の復号

`Mcrypt` で暗号化したコンテンツを復号するには、 暗号化を行った際に指定したオプションが必要です。

ここでひとつ暗号化時との大きな違いがあります。 暗号化の際にベクトルを指定しなかった場合は、コンテンツを暗号化した後で フィルタの `getVector()` メソッドを使用してベクトルを取得する必要があります。 正しいベクトルがなければ、コンテンツを復号することはできません。

オプションを指定しさえすれば、復号は暗号化と同じくらい単純なことです。

    // デフォルト設定の blowfish を使用します
    $filter = new Zend_Filter_Decrypt('myencryptionkey');

    // コンテンツの暗号化用ベクトルを設定します
    $filter->setVector('myvector');

    $decrypted = $filter->filter('encoded_text_normally_unreadable');
    print $decrypted;

mcrypt 拡張モジュールが使用できない場合は例外が発生することに注意しましょう。

また、インスタンス作成時あるいは `setEncryption()` をコールした際にすべての設定がチェックされることにも注意しましょう。 設定内容に問題があることを mcrypt が検知すると、例外がスローされます。

## OpenSSL での暗号化

`OpenSSL` 拡張モジュールをインストールすると、 `OpenSSL` アダプタが使えるようになります。 後から公開鍵を取得あるいは設定するには、`getPublicKey()` および `setPublicKey()` メソッドを使用します。 秘密鍵についても、`getPrivateKey()` および `setPrivateKey()` メソッドで取得あるいは設定できます。

    // openssl を使用し、秘密鍵を指定します
    $filter = new Zend_Filter_Encrypt(array(
        'adapter' => 'openssl',
        'private' => '/path/to/mykey/private.pem'
    ));

    // もちろん、初期化時に公開鍵を指定することもできます
    $filter->setPublicKey(array(
        '/public/key/path/first.pem',
        '/public/key/path/second.pem'
    ));

`OpenSSL` アダプタは、正しい鍵を渡さないと動作しないことに注意しましょう。

鍵自体も暗号化したい場合は、パスフレーズを `setPassphrase()` メソッドで渡します。 パスフレーズつきで暗号化したコンテンツを復号したい場合は、 公開鍵だけではなく (暗号化された鍵を復号するための) パスフレーズも必要となります。

    // openssl を使用し、秘密鍵を指定します
    $filter = new Zend_Filter_Encrypt(array(
        'adapter' => 'openssl',
        'private' => '/path/to/mykey/private.pem'
    ));

    // もちろん、初期化時に公開鍵を指定することもできます
    $filter->setPublicKey(array(
        '/public/key/path/first.pem',
        '/public/key/path/second.pem'
    ));
    $filter->setPassphrase('mypassphrase');

最後に、OpenSSL を使用した場合に受け手に渡す必要があるものをまとめます。 暗号化されたコンテンツ、パスフレーズを使用した場合はそのパスフレーズ、 そして復号用のエンベロープ鍵。これらが必要となります。

つまり、暗号化を終えたらエンベロープ鍵を取得する必要があるということです。 取得するには `getEnvelopeKey()` メソッドを使用します。

`OpenSSL` でコンテンツの暗号化を行う完全な例は、このようになります。

    // openssl を使用し、秘密鍵を指定します
    $filter = new Zend_Filter_Encrypt(array(
        'adapter' => 'openssl',
        'private' => '/path/to/mykey/private.pem'
    ));

    // もちろん、初期化時に公開鍵を指定することもできます
    $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;

    // 復号の方法は Decrypt フィルタを参照ください

### Openssl と一緒に簡単に使う方法

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.

To have a simplified usage you can set the package option to `TRUE`. The default value is `FALSE`.

    // openssl を使用し、秘密鍵を指定します
    $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;

    // 復号の方法は Decrypt フィルタを参照ください

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 `Zend_Filter_Encrypt`.

### コンテンツの圧縮

Based on the original value, the encrypted value can be a very large string. To reduce the value `Zend_Filter_Encrypt` allows the usage of compression.

The compression 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.

    // 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')
    ));

#### 同一設定での復号化

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.

## OpenSSL での復号

`OpenSSL` での復号は、暗号化と同様にシンプルです。 しかし、コンテンツを暗号化した人からすべてのデータを受け取る必要があります。 下記の例をご覧ください。

    // openssl を使用し、秘密鍵を指定します
    $filter = new Zend_Filter_Decrypt(array(
        'adapter' => 'openssl',
        'private' => '/path/to/mykey/private.pem'
    ));

    // もちろん、初期化時にエンベロープ鍵を指定することもできます
    $filter->setEnvelopeKey(array(
        '/key/from/encoder/first.pem',
        '/key/from/encoder/second.pem'
    ));

`OpenSSL` アダプタは、正しい鍵を渡さないと動作しないことに注意しましょう。

オプションで、パスフレーズを渡さなければ鍵を復号できないようにすることもできます。 そのために使用するのが `setPassphrase()` メソッドです。

    // openssl を使用し、秘密鍵を指定します
    $filter = new Zend_Filter_Decrypt(array(
        'adapter' => 'openssl',
        'private' => '/path/to/mykey/private.pem'
    ));

    // もちろん、初期化時にエンベロープ鍵を指定することもできます
    $filter->setEnvelopeKey(array(
        '/key/from/encoder/first.pem',
        '/key/from/encoder/second.pem'
    ));
    $filter->setPassphrase('mypassphrase');

最後に、コンテンツを復号します。 暗号化したコンテンツの復号を行う完全な例は、このようになります。

    // openssl を使用し、秘密鍵を指定します
    $filter = new Zend_Filter_Decrypt(array(
        'adapter' => 'openssl',
        'private' => '/path/to/mykey/private.pem'
    ));

    // もちろん、初期化時にエンベロープ鍵を指定することもできます
    $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;