CakePHP3でopenssl_encryptメソッドを使って暗号化・複合化をする方法

CakePHP3でopenssl_encryptメソッドを使って暗号化・複合化をする方法

24 回閲覧されました

みなさんこんにちは、jonioです。

今回はCakePHP3で暗号化と複合化をする方法のメモになります。

暗号化とは

「ルールを知っている人しか意味を読み取れないようにするために、特定のルールに従ってデータをぐちゃぐちゃにすること」です。

DBにデータを保存していてパスワードと同じ位見られたらまずい情報が存在している場合があります。

そういう物に対してDBに侵入した人が中身が何か分からないようにする為に行います。

突っ込んだ説明

本当は複合化という言い方は間違っています。

平文(元々のデータ)を暗号に変えるのは暗号化と言えますが暗号を平文に変えるのは複合とは言えません。

あえて言うなら平文化って感じでしょうか。

ですがみんながこれを複合化と呼ぶので複合化という呼び名になっています。

ハッシュ化との違い

ハッシュ化と同じイメージかもしれませんが全く違います。

ハッシュ化はデータを全く別の物に変えて元に戻すことができません。

しかし暗号化されたデータは元に戻すことができるし見た目が変化しているだけで元々の値として利用できます。

暗号化と複合化のコードを考える前に用語の説明をします。

(暗号)鍵

鍵と言ったり暗号鍵と言ったりします。

これは元々のデータ→暗号化したデータにする時や暗号化したデータ→元々のデータにする時に必要な道具のことです。

変換する為に必要な物といった感じです。

初期化ベクトル

暗号化する際に使うデータのことです。

平文中に同じデータが繰り返し出てきた場合に、全てが同じ暗号文に変換されると平文が推測されやすくなります。

それではセキュリティ上不安定になるので初期化ベクトルを使って同じ暗号文にならないようにします。

共通鍵暗号

暗号化・複合化をする時の鍵が同じ場合のことをこう呼びます。

それではCakePHP3で共通鍵暗号で実際の暗号化と複合化をやってみます。

AppController.php

色んなコントローラーで使うことができるように継承元のAppController.phpに暗号化と複合化のコードを書きます。

// initial_passwordの暗号化
protected function encryptPassword($data, $iterations = 5)
{
    $method = "AES-256-CBC";
    $key = '鍵の文字列';
    $iv = '初期化ベクトルの文字列';
    for ($i = 0; $i < $iterations; $i ++) {
        $data = openssl_encrypt($data, $method, $key, 0, $iv);
    }
    return $data;
}


// initial_passwordの複合化
protected function decryptPassword($data, $iterations = 5)
{
    $method = "AES-256-CBC";
    $key = '鍵の文字列';
    $iv = '初期化ベクトルの文字列';
    for ($i = 0; $i < $iterations; $i ++) {
        $data = openssl_decrypt($data, $method, $key, 0, $iv);
    }
    return $data;
}

サンプルコードはあえてpasswordカラムを暗号化・複合化しますがpasswordカラムは通常ハッシュ化しましょう。

8行目の「openssl_encrypt」メソッドで暗号化ができて21行目の「openssl_decrypt」メソッドを使うと複合化ができます。

openssl_encrypt・openssl_dencryptメソッドの使い方は下記になります。(どちらも書き方は同じなのでopenssl_encryptメソッドを使います)

openssl_encrypt($data, $method, $key, $options, $iv);

引数の意味は下記になります。

  • $data : 暗号化(複合化)をするデータ
  • $method : 暗号化(複合化)をする方法、「AES-256-CBC」は安全性が高い暗号化・複合化の方法みたいです。
  • $key : 鍵のことです。
  • $options : オプションです、0にするとオプションはなしという意味ですがとりあえずこれだけできればいいと思います。
  • $iv : 初期化ベクトルです。

オプションに関して0にするとBase64エンコード(64進数を意味する言葉で全てのデータをアルファベット(a〜z,A〜Z)と数字(0〜9)と記号(+,/)の64文字に変換)します。

7行目〜9行目で暗号化をしています。

for文を5回行っているのはセキュリティを上げる為です。

8行目で暗号化を行なっています。

5行目・18行目の鍵の文字列は16字にしないとエラーになります。

6行目・19行目の初期化ベクトルの文字列は16字にしないとエラーになります。

暗号化を5回したので複合化(20行目〜22行目)も5回しないといけません。

暗号化するコントローラー

コードを下記にします。

$user = $this->Users->get(ユーザーのid);

$encryptedInitialPassword = $this->encryptPassword($user->password);
       
$user->password = $encryptedInitialPassword;

これで暗号化ができます。

複合化するコントローラー

コードを下記にします。

$user = $this->Users->get(ユーザーのid);

$decryptedPassword = $this->decryptPassword($user->password);

これで複合化した値を確認できます。