はじめに
専門学校に通っている私、クワトロは退屈していた
「…資格対策が…だるい」
FEをとれだのAPをとれだの、LPIC、ORACLEを取れだの…
私はプログラミングがしたいんじゃ
そんな中、私はAPの資格勉強中、ある単語に目がついた
AES
そうだ、AESをCで実装してみよう
AESってなんぞ?
AESは共通鍵暗号のアルゴリズムで、今ではWPA2やらなんやらで大活躍をしている
現在までには脆弱性は見つかっていない(らしい)
AESの概念的な暗号化方法
AESは共通鍵暗号だから、もちろん暗号化、復号に使われる暗号化キーがある
AESの鍵長は128,192,256のどれかから選択ができ、もちろん数が大きいと強度も強い
(ブルートフォースと一緒)
AESは、素のキーから暗号化をするためのキーを色々して10個(128bitの場合)作成し、それぞれをXORして、換字式暗号のように書き換え、Byteをずらしていくことによって、実装ができる
ソースコード
メゾットの解説
AESは基本的に以下のように動く
ラウンドキー生成(KeyExpansion)
↓
keyと本体を16byteを4*4の表として考える
↓
ループ開始
ラウンドキーとXor(AddRoundKey)
(ラウンドキーが最後ならループ脱出)
↓
SBOXを参照して換字(SubBytes)
↓
4byteずつ、表が階段状になるようにずらす(ShiftRows)
↓
カラム混合という仕組みを使って、4byteを混合(MixColumns)
ループ
(細かいことを説明するには語彙が足りないので、先人たちにおまかせします)
復号は、この逆をするだけ
ラウンドキー生成(KeyExpension)
↓
ラウンドキーとXor(AddRoundKey)
↓
4byteずつ、階段からもとに戻す(InvShiftRows)
↓
逆SBOX(INVSBOX)を使って、換字(InvSubBytes)
↓
カラム混合を解く(InvMixColumns)
ループ
このような仕組みを使用して、AESを実装している
実行
上記のコードを実行すると以下のようになる
text = Hello world AES
memory = 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x20, 0x41, 0x45, 0x53, 0x00,
text = ����M%<J�����@h
memory = 0x9d, 0x8d, 0x98, 0xa1, 0x4d, 0x25, 0x3c, 0x4a, 0xca, 0xf4, 0xe6, 0xe8, 0x10, 0xd6, 0x40, 0x68,
text = Hello world AES
memory = 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x20, 0x41, 0x45, 0x53, 0x00,
1つ目→もともとの文字列
2つ目→暗号化された文字列
3つ目→暗号から複合された文字列
作ってみて、わかったこと
- AESは、思ったより単純であること
Xor+バイトごとのShift、カラム混合の3つの繰り返しをしているだけで
これで本当に暗号化できているのだろうかと、少し心配になってしまった
わからなかったこと
…有限体(カラム体)がわからん
Wikipediaや先人の書いたQiitaたちを参照したから、なんとか形になったが
依然、カラム混合の既約多項式や、乗算の実装がどうしてそう実装するのかとかがわからなかった
(その部分はChatGPT君に補助してもらいながら作成した)
もともと、高校数学すらできてなかった私には荷が重かったのだろうか
まとめ
- AESは、想像以上に単純であった
- AESは、XOR,置換、ByteShift、カラム混合からできている
- 有限体という、すんごい計算方法を採用している