javascript⇔PHPの暗号と復号(上)
ハイブリッドアプリとAPIサーバ間で通信を行う際、データを暗号化する必要がある場合、アプリ側の暗号復号処理はjavascriptで実装しないと行けません。javascript暗号化ライブラリについて少し調べたところ、個人的にお勧めできるのは以下二つです。
ある開発者が趣味で開発したものですが、今一番使われているJS暗号化ライブラリだと思います。ドキュメントが結構シンプルですが、わからない場合stackflowで調べたら、大体解決できます。ただし、今後がちゃんとメンテナンスされるか、ちょっと心配です。
Stanford Computer Security Labが中心で進めているプロジェクトです。まだそんなに使われていないのですが、将来性が高いと思います。
今回は利用者が多いCryptoJSを選びました。そして、以下の前提で実装します。
バックエンド
・PHP 5.4
・mcrypt利用
フロントエンド
・Javascript
・CryptoJS利用
暗号化
・方式:AES
・アルゴリズム:RIJNDAEL_128
・モード:CBC
まず、javascriptで暗号化して、PHPで復号する方法を紹介します。
早速、コードが以下になります。
javascriptでデータ暗号化
// 共通鍵生成処理 function createKey() { // パスワード、SALT、キーサイズ、往復回数指定で共通鍵を作成 var key = CryptoJS.PBKDF2('123456789abcdefg', 'abcdefghijklmnopqrstuv1234567890', {keySize: 4, iterations: 500}); return key; } // 暗号化処理 function encrypt(dataPlain, key) { // 初期化ベクトルを作成 var iv = CryptoJS.enc.Hex.parse('12345678901234567890123456789012'); // 暗号化 var dataCipher = CryptoJS.AES.encrypt(JSON.stringify(dataPlain), key, {iv: iv}); return dataCipher; } // BASE64にエンコードされた共通鍵は事前にPHP側と共有 var key = createKey(); var keyBase64 = key.toString(CryptoJS.enc.Base64); // では暗号化しましょう var dataPlain = 'encrypt me, please!'; var dataCipher = encryp(dataPlain, key); // PHP側に送るデータ var params = { "data_cipher_base64": dataCipher.ciphertext.toString(CryptoJS.enc.Base64), "iv_base64": dataCipher.iv.toString(CryptoJS.enc.Base64) };
PHPでデータを復号
<?php public static function decrypt($data_cipher_base64, $key_base64, $iv_base64) { // 受信した暗号化されたデータとivをデコード $data_cipher = base64_decode($data_cipher_base64); $iv = base64_decode($iv_base64); // 事前に共有されているBASE64共通鍵をデコード $key = base64_decode($key_base64); // 復号する $data_plain_padded = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, $data_cipher, MCRYPT_MODE_CBC, $iv); // デフォルトでPkcs7パディングされるので、削除しないと $length = strlen($data_plain_padded); $pad = ord($data_plain_padded[$length - 1]); $data_plain = substr($data_plain_padded, 0, -$pad); $data = json_decode($data_plain, true); return $data; }
以上で、次回はPHPでの暗号化とjavascriptでの復号を紹介します。