Mam's WebSite

Mamの覚書Q&A検索


大項目:「 PHP 」 - 中項目:「 その他 」

「 暗号化、複合化したい 」

AES256で暗号化、複合化を行うには
openssl_encrypt
openssl_decrypt


回答

AES256はブロック長128bit(16byte)、鍵長256bit(32byte)のブロック暗号です。
ECBモードはメッセージの機密性の保持には向かないため、現在、最も広く使用されているCBCモード(※1)を使用します。
※1)CBCモード
ブロック毎に前のブロックの暗号化の結果とXORした値に暗号化処理を行う。ただし、最初のブロックは初期ベクトルとXORした値に暗号化処理を行う。
 
使用する関数は以下
openssl_encrypt("暗号化するデータ", "暗号化方式", "暗号化キー", [オプション[,"初期ベクトル"]] );
オプションは、0 又は OPENSSL_RAW_DATA と OPENSSL_ZERO_PADDING の OR値
  OPENSSL_RAW_DATA:戻り値をBASE64エンコードしない
  OPENSSL_ZERO_PADDING:ブロック内の余り部分に余ったバイト数を入れない(Paddingしない)
  0:戻り値(暗号化した値)をBASE64エンコードしてPaddingして返す
openssl_decrypt("暗号化データ", "暗号化方式", "暗号化キー", [オプション[,"初期ベクトル"]] );

ソース

//暗号化鍵と初期ベクトルが固定の場合の暗号化複合化[非推奨]
$data="この文字列を暗号化します。";
$key="abcdefghijklmnopqrstuvwxyzABCDEF";//32文字
$iv ="1234567890123456";                //16文字
echo $data."<br>¥n";
$enc=encrypt1($data,$key,$iv);//暗号化
echo $enc."<br>¥n";
$dec=decrypt1($enc ,$key,$iv);//複合化
echo $dec."<br>¥n";
 
function encrypt1($data,$key,$iv){
  return openssl_encrypt($data, 'AES-256-CBC', $key, 0, $iv);
}
function decrypt1($enc,$key,$iv){
  return openssl_decrypt($enc,  'AES-256-CBC', $key, 0, $iv);
}
--------------------------------------------------------------------------------
//パスワードと初期ベクトルが固定の場合の暗号化複合化(salt値をランダム値で生成)
$data="この文字列を暗号化します。";
$pw ="Himitsu_no_Password";
$iv ="1234567890ABCDEF";//16文字必要
echo $data."<br>¥n";
$enc=encrypt2($data,$pw,$iv);
echo $enc."<br>¥n";
$dec=decrypt2($enc,$pw,$iv);
echo $dec."<br>¥n";
 
function encrypt2($data,$pw,$iv){
  $salt = openssl_random_pseudo_bytes(16);//ランダムなsalt値
  $key  = hash('sha256', $pw.$salt, true);//パスワード+salt値から鍵生成
  $enc = openssl_encrypt($data, 'AES-256-CBC', $key, OPENSSL_RAW_DATA, $iv);
  return base64_encode($salt.$enc);
}
function decrypt2($enc,$pw,$iv){
  $data=base64_decode($enc);
  $salt=substr($data,0,16);//先頭16byteがsalt値
  $ct  =substr($data,16);  //17バイト以降が暗号化データ
  $key =hash('sha256', $pw.$salt, true);
  return openssl_decrypt($ct, 'AES-256-CBC', $key, OPENSSL_RAW_DATA, $iv);
}
 
--------------------------------------------------------------------------------
//パスワードのみ固定(salt値をランダム値で生成、鍵と初期ベクトルをパスワード+salt値から生成)
$data="この文字列を暗号化します。";
$pw ="Himitsu_no_Password";
echo $data."<br>¥n";
$enc=encrypt3($data,$pw);
echo $enc."<br>¥n";
$dec=decrypt3($enc,$pw);
echo $dec."<br>¥n";
 
function encrypt3($data,$pw){
  $salt=openssl_random_pseudo_bytes(16);//ランダムなsalt値
  $hash=hash('sha512',$pw.$salt,true);
  $key=substr($hash,0,32);  //暗号化鍵
  $iv =substr($hash,32,16); //初期ベクトル
  $enc=openssl_encrypt($data,'AES-256-CBC',$key,OPENSSL_RAW_DATA,$iv);
  return base64_encode($salt.$enc);//salt値(16byte)に暗号化データを連結して返す
}
function decrypt3($enc,$pw){
  $data=base64_decode($enc);
  $salt=substr($data,0,16);//先頭16byteがsalt値
  $ct=substr($data,16);    //17byte目以降が暗号化データ
  $hash=hash('sha512',$pw.$salt,true);
  $key=substr($hash,0,32);  //暗号化鍵
  $iv=substr($hash,32,16);  //初期ベクトル
  return openssl_decrypt($ct,'AES-256-CBC',$key,OPENSSL_RAW_DATA,$iv);
}

Copyright 2019 Mam