INNOBASE技術ブログ

技術的なことエンジニア的なこと制作的なこと全般

javascript⇔PHPの暗号と復号(下)

前回の記事でCryptoJSを利用して、javascriptでデータを暗号化し、phpで複合化する方法を紹介しましたが、今回は引き続き、phpでの暗号とjsでの復号を紹介します。

改めて、以下の前提で実装します。

バックエンド
・PHP 5.4
・mcrypt利用

フロントエンド
・Javascript
・CryptoJS利用

暗号化
・方式:AES
・アルゴリズム:RIJNDAEL_128
・モード:CBC

早速、コードが以下になります。

PHPでデータを復号

<?php
    public static function encrypt($data, $key_base64, $iv)
    {
        // 送信するデータをエンコード
        $data_plain = json_encode($data);

        // Pkcs7パディングを実施
        $block_size = mcrypt_get_block_size(ENCRYPTION_ALGORITHM, ENCRYPTION_MODE);
        $pad = $block_size - (strlen($data_plain) % $block_size);
        $data_plain_padded = $data_plain . str_repeat(chr($pad), $pad);

        // 事前に共有されているBASE64共通鍵をデコード
        $key = base64_decode($key_base64);
        
        // 暗号化する
        $data_cipher = mcrypt_encrypt(ENCRYPTION_ALGORITHM, $key, $data_plain_padded, ENCRYPTION_MODE, $iv);
        $data_cipher_base64 = base64_encode((String) $data_cipher);

        return $data;
    }

javascriptでデータ暗号化

    // 共通鍵生成処理
    function createKey() {

        // パスワード、SALT、キーサイズ、往復回数指定で共通鍵を作成
        var key = CryptoJS.PBKDF2('123456789abcdefg', 'abcdefghijklmnopqrstuv1234567890', {keySize: 4, iterations: 500});

        return key;
    }

    // 復号化処理
    function decrypt(dataCipher, ivString) {
        var key = createKey();

        // 初期化ベクトルを作成
        var iv = CryptoJS.enc.Base64.parse(ivString);

        // 復号化
        var dataPlain = CryptoJS.AES.decrypt(dataCipher, key, {iv: iv});

       // JSONデータにデコード
       var data = JSON.parse(CryptoJS.enc.Utf8.stringify(dataPlain));

        return data;
    }

また、前回の記事でコメントを頂いたjserさんのご指摘通り、各ブラウザは既にW3CのWebCryptoAPIをサポートし始めたので、今後はWEBクライアント側暗号の標準になるでしょう