ブロック暗号(AES)

平文をある決まったサイズに分割し、その分割した固まりごとに暗号化する方法
端数があれば、パディングと呼ばれる方法で一つのブロックを作って処理する
ブロックごとに暗号化モードに応じた処理を行う

1970年にDESと呼ばれるブロック暗号が使われていた(64ビット、鍵長は56ビット)
DESに変わる標準的暗号としてAES(Advanced Encryption Standard)が選出された

### AES概要
AESブロックは128ビットで鍵長は128, 192, 256ビットを選べる
AESの暗号化は、秘密鍵の初期設定後(AddRoundKey)、ラウンド関数と呼ばれる処理を一定回数繰り返す 
最後に最終ラウンド関数と呼ばれる処理をして暗号化が完了する
ラウンド関数は鍵長に応じて9、11、13回行う。鍵長が大きいほど処理に時間がかかる
AESが理想的なブロック暗号なら全数探索のO(2^128)の計算コストがかかる

1. RoundKeyを作成する
2. 128ビットである1ブロックを8ビットずつの16個のデータX0からX15に分割する
3. 4×4のマス目の正方形に入れる
4. Roudkeyとマス目のデータの排他的論理和を取る

### ラウンド関数
ラウンド関数はSubBytes, ShiftRows, MixColumnsとAddRoundKeyを順番に処理する
L SubBytesはS -Boxという換字表による換字式暗号を行う
ShiftRows: 横の列ごとデータを左にずらす
MixColumns: 縦の列ごとにある決められた行列Aを掛ける演算をする(行列の成分)
最終ラウンド関数: MixColumnsを除いたSubByte, ShiftRows, AddRoundKeyの処理をする
AES-NI: IntelやAMDのCPUに搭載されているAESを高速処理するための専用命令 ARMアーキテクチャでも同様の専用命令を搭載していることがある

// 鍵
$key = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa';
// 初期ベクトル
$iv = 'bbbbbbbbbbbbbbbb';
$str = 'hello world';

// 暗号化
$str = openssl_encrypt($str, 'AES-256-CBC', $key, 0, $iv);
echo "${str}\n";

// 複合する
$str = openssl_decrypt($str, 'AES-256-CBC', $key, 0, $iv);
echo "${str}\n";

$ php index.php
9due8hN1Y3j3t6sx/WnryA==
hello world