暗号化サービス

重要

パスワードの保存に、このライブラリや他の暗号化ライブラリを使用しないでください!パスワードは代わりにハッシュ化する必要があり、PHP の パスワードハッシュ拡張 を介して行う必要があります。

暗号化サービスは、双方向対称(秘密鍵)データ暗号化を提供します。サービスは、以下で説明するように、パラメータに合わせて暗号化ハンドラをインスタンス化および/または初期化します。

暗号化サービスハンドラは、CodeIgniter のシンプルな EncrypterInterface を実装する必要があります。適切な PHP 暗号拡張機能またはサードパーティ製ライブラリを使用するには、サーバーに追加のソフトウェアをインストールする必要がある場合や、PHP のインスタンスで明示的に有効にする必要がある場合があります。

現在、次の PHP 拡張機能がサポートされています。

これは完全な暗号化ソリューションではありません。公開鍵暗号化など、より多くの機能が必要な場合は、OpenSSL または他の 暗号化拡張機能 の直接使用を検討することをお勧めします。 Halite(libsodium 上に構築された O-O パッケージ)のような、より包括的なパッケージも可能です。

PHP 7.2 以降で非推奨になったため、MCrypt 拡張機能のサポートは廃止されました。

暗号化ライブラリの使用

CodeIgniter のすべてのサービスと同様に、Config\Services を介してロードできます。

<?php

$encrypter = \Config\Services::encrypter();

開始キーを設定していると仮定すると(ライブラリの設定を参照)、データの暗号化と復号化は簡単です。適切な文字列を encrypt() および/または decrypt() メソッドに渡します。

<?php

$plainText  = 'This is a plain-text message!';
$ciphertext = $encrypter->encrypt($plainText);

// Outputs: This is a plain-text message!
echo $encrypter->decrypt($ciphertext);

それだけです!暗号化ライブラリは、プロセス全体がすぐに利用できる暗号的に安全であるために必要なすべてを実行します。心配する必要はありません。

ライブラリの設定

上記の例では、app/Config/Encryption.php にある構成設定を使用しています。

オプション

使用可能な値(括弧内はデフォルト)

key

暗号化キースターター

driver

優先ハンドラ、例:OpenSSL または Sodium (OpenSSL)

digest

メッセージダイジェストアルゴリズム (SHA512)

blockSize

[SodiumHandler のみ] パディング長(バイト単位)(16)

cipher

[OpenSSLHandler のみ] 使用する暗号 (AES-256-CTR)

encryptKeyInfo

[OpenSSLHandler のみ] 暗号化キー情報 ('')

authKeyInfo

[OpenSSLHandler のみ] 認証キー情報 ('')

rawData

[OpenSSLHandler のみ] 暗号化テキストを raw にする必要があるかどうか (true)

Services の呼び出しに独自の構成オブジェクトを渡すことで、構成ファイルの設定を置き換えることができます。$config 変数は、Config\Encryption クラスのインスタンスである必要があります。

<?php

$config         = new \Config\Encryption();
$config->key    = 'aBigsecret_ofAtleast32Characters';
$config->driver = 'OpenSSL';

$encrypter = \Config\Services::encrypter($config);

CI3 との互換性を維持するための設定

バージョン 4.3.0 の新機能。

v4.3.0 以降では、CI3 の暗号化で暗号化されたデータを復号化できます。このようなデータを復号化する必要がある場合は、次の設定を使用して互換性を維持してください。

<?php

use Config\Encryption;
use Config\Services;

$config         = new Encryption();
$config->driver = 'OpenSSL';

// Your CI3's 'encryption_key'
$config->key = hex2bin('64c70b0b8d45b80b9eba60b8b3c8a34d0193223d20fea46f8644b848bf7ce67f');
// Your CI3's 'cipher' and 'mode'
$config->cipher = 'AES-128-CBC';

$config->rawData        = false;
$config->encryptKeyInfo = 'encryption';
$config->authKeyInfo    = 'authentication';

$encrypter = Services::encrypter($config, false);

サポートされている HMAC 認証アルゴリズム

HMAC メッセージ認証の場合、暗号化ライブラリは SHA-2 ファミリーのアルゴリズムの使用をサポートしています。

アルゴリズム

生の長さ(バイト)

16 進数エンコードされた長さ(バイト)

SHA512

64

128

SHA384

48

96

SHA256

32

64

SHA224

28

56

MD5 や SHA1 などの他の一般的なアルゴリズムを含めない理由は、それらがもはや十分に安全とは考えられていないためであり、そのため、その使用を推奨したくありません。それらを絶対に使用する必要がある場合は、PHP のネイティブ hash_hmac() 関数を使用して簡単に実行できます。

より強力なアルゴリズムは、将来登場し、広く利用可能になるにつれて追加される予定です。

デフォルトの動作

デフォルトでは、暗号化ライブラリは OpenSSL ハンドラを使用します。このハンドラは、AES-256-CTR アルゴリズム、設定されたキー、および SHA512 HMAC 認証を使用して暗号化します。

暗号化キーの設定

暗号化キーは、使用中の暗号化アルゴリズムで許可されている限り長くする必要があります。AES-256 の場合、それは 256 ビットまたは 32 バイト(文字)の長さです。

キーはできるだけランダムである必要があり、通常のテキスト文字列やハッシュ関数の出力などであってはなりません。適切なキーを作成するには、暗号化ライブラリの createKey() メソッドを使用できます。

<?php

// $key will be assigned a 32-byte (256-bit) random key
$key = \CodeIgniter\Encryption\Encryption::createKey();

// for the SodiumHandler, you can use either:
$key = sodium_crypto_secretbox_keygen();
$key = \CodeIgniter\Encryption\Encryption::createKey(SODIUM_CRYPTO_SECRETBOX_KEYBYTES);

キーは app/Config/Encryption.php に保存できます。または、独自のストレージメカニズムを設計し、暗号化/復号化時にキーを動的に渡すこともできます。

キーを app/Config/Encryption.php に保存するには、ファイルを開いて設定します。

<?php

namespace Config;

use CodeIgniter\Config\BaseConfig;

class Encryption extends BaseConfig
{
    public $key = 'YOUR KEY';

    // ...
}

キーまたは結果のエンコード

createKey() メソッドは、バイナリデータを出力することに気づくでしょう。これは扱いが難しいため(つまり、コピー&ペーストで破損する可能性があります)、bin2hex() または base64_encode を使用して、より使いやすい方法でキーを操作できます。例:

<?php

// Get a hex-encoded representation of the key:
$encoded = bin2hex(\CodeIgniter\Encryption\Encryption::createKey(32));

// Put the same value with hex2bin(),
// so that it is still passed as binary to the library:
$key = hex2bin('your-hex-encoded-key');

暗号化の結果についても同じ手法が役立つ場合があります。

<?php

// Encrypt some text & make the results text
$encoded = base64_encode($encrypter->encrypt($plaintext));

キーの保存におけるプレフィックスの使用

暗号化キーを保存する際に、2 つの特別なプレフィックス、hex2bin: および base64: を利用できます。これらのプレフィックスがキーの値の直前にある場合、Encryption はキーをインテリジェントに解析し、バイナリ文字列をライブラリに渡します。

<?php

namespace Config;

use CodeIgniter\Config\BaseConfig;

class Encryption extends BaseConfig
{
    // In Encryption, you may use
    public $key = 'hex2bin:<your-hex-encoded-key>';
    // or
    public $key = 'base64:<your-base64-encoded-key>';
    // ...
}

同様に、これらのプレフィックスを .env ファイルでも使用できます。

// For hex2bin
encryption.key = hex2bin:<your-hex-encoded-key>

// or
encryption.key = base64:<your-base64-encoded-key>

パディング

メッセージの長さは、その性質に関する多くの情報を提供する場合があります。メッセージが「はい」、「いいえ」、「たぶん」のいずれかである場合、メッセージを暗号化しても意味がありません。長さが分かれば、メッセージの内容が分かるからです。

パディングは、長さを特定のブロックサイズの倍数にすることで、これを緩和する手法です。

パディングは、libsodium のネイティブな sodium_pad および sodium_unpad 関数を使用して SodiumHandler に実装されています。これには、暗号化前に平文メッセージに追加され、復号後に削除されるパディング長(バイト単位)の使用が必要です。パディングは、Config\Encryption$blockSize プロパティを介して構成できます。この値はゼロより大きい必要があります。

重要

独自のパディング実装を考案しないことをお勧めします。常にライブラリのより安全な実装を使用する必要があります。また、パスワードをパディングしないでください。パスワードの長さを隠すためにパディングを使用することは推奨されません。パスワードをサーバーに送信したいクライアントは、代わりにハッシュ化する必要があります(ハッシュ関数の単一の反復でも)。これにより、送信されるデータの長さが一定になり、サーバーがパスワードのコピーを簡単に取得できなくなります。

暗号化ハンドラーに関する注意

OpenSSLに関する注意

OpenSSL拡張機能は、長い間PHPの標準機能でした。

CodeIgniterのOpenSSLハンドラーは、AES-256-CTR暗号を使用します。

構成で提供されるキーは、暗号化用と認証用の2つの他のキーを派生させるために使用されます。これは、HMACベースの鍵導出関数(HKDF)として知られる手法によって実現されます。

Sodiumに関する注意

Sodium拡張機能は、PHP 7.2.0以降、PHPにデフォルトでバンドルされています。

Sodiumは、エンドツーエンドのシナリオで秘密メッセージを送信する際に、暗号化にXSalsa20、MACにPoly1305、キー交換にXS25519アルゴリズムを使用します。対称暗号などの共有キーを使用して文字列を暗号化および/または認証する場合、Sodiumは暗号化にXSalsa20アルゴリズムを使用し、認証にHMAC-SHA512を使用します。

CodeIgniterのSodiumHandlerは、暗号化または復号化セッションごとにsodium_memzeroを使用します。各セッション後、メッセージ(平文または暗号文)と開始キーはバッファから消去されます。新しいセッションを開始する前に、キーを再度提供する必要がある場合があります。

メッセージ長

暗号化された文字列は、通常、元の平文文字列よりも長くなります(暗号に依存します)。

これは、暗号アルゴリズム自体、暗号文の先頭に追加される初期化ベクトル(IV)、および先頭に追加されるHMAC認証メッセージの影響を受けます。さらに、暗号化されたメッセージは、使用中の文字セットに関係なく、ストレージと送信に安全になるようにBase64でエンコードされています。

データストレージメカニズムを選択する際には、この情報に留意してください。たとえば、Cookieは4Kの情報しか保持できません。

暗号化サービスを直接使用する

暗号化ライブラリの使用で説明したように、Servicesを使用する代わりに(または加えて)、直接「Encrypter」を作成するか、既存のインスタンスの設定を変更できます。

<?php

// create an Encryption instance
$encryption = new \CodeIgniter\Encryption\Encryption();

// reconfigure an instance with different settings
$encrypter = $encryption->initialize($config);

$configConfig\Encryption クラスのインスタンスでなければならないことに注意してください。

クラスリファレンス

class CodeIgniter\Encryption\Encryption
static createKey([$length = 32])
パラメータ
  • $length (int) – 出力長

戻り値

指定された長さの擬似乱数暗号キー、または失敗した場合はfalse

戻り値の型

文字列

オペレーティングシステムのソース(つまり /dev/urandom)からランダムなデータを取得することにより、暗号キーを作成します。

initialize([Encryption $config = null])
パラメータ
  • $config (Config\Encryption) – 構成パラメータ

戻り値

CodeIgniter\Encryption\EncrypterInterface インスタンス

戻り値の型

CodeIgniter\Encryption\EncrypterInterface

例外

CodeIgniter\Encryption\Exceptions\EncryptionException

ライブラリを初期化(構成)して、異なる設定を使用します。

<?php

$encrypter = $encryption->initialize(['cipher' => 'AES-256-CTR']);

詳細については、ライブラリの構成セクションを参照してください。

CodeIgniter\Encryption\EncrypterInterface
encrypt($data[, $params = null])
パラメータ
  • $data (string) – 暗号化するデータ

  • $params (array|string|null) – 構成パラメータ(キー)

戻り値

暗号化されたデータ

戻り値の型

文字列

例外

CodeIgniter\Encryption\Exceptions\EncryptionException

入力データを暗号化し、その暗号文を返します。

パラメータを2番目の引数として渡す場合、$paramsが配列の場合、key要素はこの操作の開始キーとして使用されます。または、開始キーを文字列として渡すことができます。

SodiumHandlerを使用しており、実行時に別のblockSizeを渡したい場合は、$params配列にblockSizeキーを渡します。

<?php

$ciphertext = $encrypter->encrypt('My secret message');
$ciphertext = $encrypter->encrypt('My secret message', ['key' => 'New secret key']);
$ciphertext = $encrypter->encrypt('My secret message', ['key' => 'New secret key', 'blockSize' => 32]);
$ciphertext = $encrypter->encrypt('My secret message', 'New secret key');
$ciphertext = $encrypter->encrypt('My secret message', ['blockSize' => 32]);
decrypt($data[, $params = null])
パラメータ
  • $data (string) – 復号化するデータ

  • $params (array|string|null) – 構成パラメータ(キー)

戻り値

復号化されたデータ

戻り値の型

文字列

例外

CodeIgniter\Encryption\Exceptions\EncryptionException

入力データを復号化し、平文で返します。

パラメータを2番目の引数として渡す場合、$paramsが配列の場合、key要素はこの操作の開始キーとして使用されます。または、開始キーを文字列として渡すことができます。

SodiumHandlerを使用しており、実行時に別のblockSizeを渡したい場合は、$params配列にblockSizeキーを渡します。

<?php

echo $encrypter->decrypt($ciphertext);
echo $encrypter->decrypt($ciphertext, ['key' => 'New secret key']);
echo $encrypter->decrypt($ciphertext, ['key' => 'New secret key', 'blockSize' => 32]);
echo $encrypter->decrypt($ciphertext, 'New secret key');
echo $encrypter->decrypt($ciphertext, ['blockSize' => 32]);