暗号化サービス
重要
パスワードの保存に、このライブラリや他の暗号化ライブラリを使用しないでください!パスワードは代わりにハッシュ化する必要があり、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 ( |
digest |
メッセージダイジェストアルゴリズム ( |
blockSize |
[SodiumHandler のみ] パディング長(バイト単位)( |
cipher |
[OpenSSLHandler のみ] 使用する暗号 ( |
encryptKeyInfo |
[OpenSSLHandler のみ] 暗号化キー情報 ( |
authKeyInfo |
[OpenSSLHandler のみ] 認証キー情報 ( |
rawData |
[OpenSSLHandler のみ] 暗号化テキストを raw にする必要があるかどうか ( |
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);
$config
は Config\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]);