pythonで暗号演算 ~AES-CMAC編~

python,暗号演算,pycryptodome,python,暗号演算

今回はAES-CMACの勉強と、pythonのライブラリpycryptodomeを使用して実際にMAC生成をしてみました。

初めに

現在業務で組み込みソフトにおける、HSMと呼ばれるモジュールのソフト開発に取り組んでおります。

HSMは機器内の暗号処理における、鍵管理や暗号処理そのものを提供するハードウェアであり、今回この業務に携わるにあたり暗号分野の勉強が必要不可欠となってきました。

AES-CMACとは

まずAESとは、 Advanced Encryption Standard(高度暗号化標準)の略となり、特定の長さのデータ(ブロック)を単位として処理を行う「ブロック暗号」の一種です。

AES-CMACは、この中のAES-CBC暗号アルゴリズムを利用することにより、特定のメッセージから任意のメッセージ認証コードを出力させます。

端的に言ってしまえば、AES-CMACはメッセージの改ざんを検知するためのハッシュ関数です。

ハッシュ関数とは、任意長のビット列から規則性のない固定長のビット列(識別子)を生成する関数、手順のことをいいます。 

このハッシュ関数使用時に使用するカギを通信相手同士で共有することで、メッセージの改ざんを検知することが出来ます。

上記のような通信以外にも、セキュアブートと言ってこれから動作させようとしているソフトが問題ないか確認するため、起動時に自身でMAC検証を行うこともあります。

AES-CMACに関するもっと詳しい話について、興味があれば以下を参照いただければと思います。

実装

ライブラリ (PyCryptodome)

pipから暗号演算が行えるライブラリをインポート。

pip install pycryptodome

詳細についてはこちらを参照してください。

ソースコード

計算とかはライブラリがやってくれるのでデータと鍵値を渡すだけ。

なお、今回のテストコードで使用したテストベクターは、上記RFCのURLから引っ張ってきたものとなります。(「4. Test Vectors」参照)

import Crypto.Cipher.AES as AES
from Crypto.Hash import CMAC

# 鍵値
key = bytes.fromhex("2b7e151628aed2a6abf7158809cf4f3c")

# メッセージサイズ16byte
data = bytes.fromhex("6bc1bee22e409f96e93d7e117393172a")
# CMAC生成1
h1 = CMAC.new(key, data, ciphermod=AES)
print("h1:" + h1.digest().hex())
# CMAC生成2
h2 = CMAC.new(key, ciphermod=AES)
h2.update(data)
print("h2:" + h2.digest().hex())

# メッセージサイズ64byte
M1 = bytes.fromhex("6bc1bee22e409f96e93d7e117393172a")
M2 = bytes.fromhex("ae2d8a571e03ac9c9eb76fac45af8e51")
M3 = bytes.fromhex("30c81c46a35ce411e5fbc1191a0a52ef")
M4 = bytes.fromhex("f69f2445df4f9b17ad2b417be66c3710")
# CMAC生成3
h3 = CMAC.new(key, ciphermod=AES)
h3.update(M1)
h3.update(M2)
h3.update(M3)
h3.update(M4)
print("h3:" + h3.digest().hex())

出力結果もテストベクターの期待値となりました。

h1:070a16b46b4d4144f79bdd9dd04a287c
h2:070a16b46b4d4144f79bdd9dd04a287c
h3:51f0bebf7e3b9d92fc49741779363cfe