AES256による暗号化/復号をPHPとJavaでやる
お疲れ様です!
GMOリサーチの石黒です!
さて、皆さんも急にAESで暗号化したくなる衝動に駆られることがあると思います。
そんな皆さんのために今回は、JavaとPHP、PHPはOpenSSLとMcryptの、計3種類の方法で暗号化/複合のコードを書いていきます。
AES256アルゴリズム、ECBモード、PKCS5パディングで実装しています。
バージョン
Java 1.8
PHP 5.6
Java
Javaでは、デフォルトでAESの鍵の長さは128bitしか扱うことができません。
256bitの鍵を扱うためには、Javaのポリシーファイルを差し替える必要があります。
詳細はJavaでAES256を使用できるようにするなどの記事をご参照ください。
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;
public class aes01 {
public static void main(String[] args) {
try {
byte[] key = DatatypeConverter.parseBase64Binary(
"キーをbase64エンコードした文字列");
SecretKeySpec sks = new SecretKeySpec(key, "AES");
byte[] input = "暗号化したい文字列".getBytes();
// 暗号化
Cipher c = Cipher.getInstance("AES/ECB/PKCS5Padding");
c.init(Cipher.ENCRYPT_MODE, sks);
byte encrypted[] = c.doFinal(input);
System.out.println(DatatypeConverter.printBase64Binary(encrypted));
// 復号
c.init(Cipher.DECRYPT_MODE, sks);
byte decrypted[] = c.doFinal(encrypted);
System.out.println(new String(decrypted));
} catch (Exception e) {
e.printStackTrace();
}
}
}
PHP(OpenSSL)
PHP5.3以降での暗号化はOpenSSLで行ないます。
<?php
$key = base64_decode("キーをbase64エンコードした文字列");
$input = '暗号化したい文字列';
// 暗号化
$encrypted = openssl_encrypt($input, 'aes-256-ecb', $key);
echo $encrypted;
// 復号
$decrypted = openssl_decrypt($encrypted, 'aes-256-ecb', $key);
echo $decrypted;
PHP(Mcrypt)※非推奨
非推奨な方法での暗号化です。
必要な時以外は使用しないようにしましょう。
というか面倒臭すぎます。
<?php
$key = base64_decode('キーをbase64エンコードした文字列');
$input = '暗号化したい文字列';
$crypt = new Crypt($key);
// 暗号化
$encrypted = base64_encode($crypt->encrypt($input));
echo $encrypted;
// 復号
$decrypted = $crypt->decrypt(base64_decode($encrypted));
echo $decrypted;
class Crypt {
private $__encrypt_key = null;
public $iv = null;
public function __construct($encrypt_key) {
$this->__encrypt_key = $encrypt_key;
}
public function encrypt($input, $algo = MCRYPT_RIJNDAEL_128, $mode = MCRYPT_MODE_ECB) {
list($size, $td) = $this->__open($algo, $mode);
$input = $this->__pkcs5Pad($input, $size);
$data = mcrypt_generic($td, $input);
$this->__close($td);
return $data;
}
public function decrypt($input, $algo = MCRYPT_RIJNDAEL_128, $mode = MCRYPT_MODE_ECB) {
list ($size, $td) = $this->__open($algo, $mode);
$input = mdecrypt_generic($td, $input);
$data = $this->__pkcs5Unpad($input);
$this->__close($td);
return $data;
}
private function __open($algo, $mode) {
$size = mcrypt_get_block_size($algo, $mode);
$td = mcrypt_module_open($algo, '', $mode, '');
$this->iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
mcrypt_generic_init($td, $this->__encrypt_key, $this->iv);
return array($size, $td);
}
private function __close($td){
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
}
public static function __pkcs5Pad($text, $blocksize) {
$pad = $blocksize - (strlen($text) % $blocksize);
return $text . str_repeat(chr($pad), $pad);
}
public static function __pkcs5Unpad($text) {
$pad = ord($text{strlen($text)-1});
if ($pad > strlen($text)) return false;
if (strspn($text, chr($pad), strlen($text) - $pad) !== $pad) return false;
return substr($text, 0, -1 * $pad);
}
}
MCRYPT_RIJNDAEL_128 というものが、AES256に相当するものらしいです。
MCRYPT_RIJNDAEL_256 というアルゴリズムもありますが、これではないので注意。
一応、汎用的に使えるよう、アルゴリズムとモードの変更はできるようになっていますが、
本当に使えるかは不明です。
おわりに
以上です!
これでAES暗号化したい衝動に駆られても大丈夫ですね。
PHPのOpenSSLが非常にシンプルで良かったと思いました。(小並感)
Author And Source
この問題について(AES256による暗号化/復号をPHPとJavaでやる), 我々は、より多くの情報をここで見つけました https://qiita.com/Gro/items/e8915562670cd8310b2f著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .