Fernetの使い方
概要
Fernetはpyca/cryptographyの共通鍵暗号を実装しています。とにかく簡単に暗号/復号の処理を実現できるようになっています。FeernetはAES128ビットCBCモードで実現されており,鍵長やアルゴリズムは選ぶことができません。
Fernetで暗号化を実行すると,平文はトークンと呼ばれるオブジェクトになります。復号するときは,トークンをそのまま復号メソッドに適用します。
Fernetの面白いところは,時刻を設定することができることです。復号時に時刻を設定すると,その時刻より古い暗号文は復号することができません。これによって,時間制限のある暗号を運用することができます。
Fernetのクラス
| メソッド | 概要 |
|---|---|
| generate_key() | Fernetで利用する鍵を生成します。暗/復号を行うには,この鍵を利用する必要があります。 |
| encrypt(data) | Fernetの鍵を利用してdataを暗号化します。トークンと呼ばれる暗号文を取得することができます。 |
| decrypt(token, ttl=None) | 暗号文であるトークンを復号します。オプションでttlを指定すると,タイムスタンプの評価を行うことができます。 |
| extract_timestamp(token) | トークンのタイムスタンプを取得することができます |
鍵の危殆化に備えて,鍵のローテーションを行うことができるMultiFernetがあります。メソッドに鍵のlistを渡して,複数の鍵を利用可能にします。
| メソッド | 概要 |
|---|---|
| rotate(msg) | Fernetで持っている鍵を使って,msgを再暗号化します。 |
復号時にエラーになった場合は,エラーが発生します。
Fernetの仕様
Fernetの仕様については,特に知らなくても利用する分には困りません。鍵やトークンのフォーマットをここでは紹介します。
鍵のフォーマット
鍵は普通のビット列です。実際にはBase64エンコードされています。
SigningKey || EncryptionKeyこのように,署名用の鍵と暗号用の鍵が単純に連結されています。署名用の鍵は,トークンに付加するHMACを生成するために利用します。
トークンのフォーマット
Fernetで暗号化処理を行うと,次のフォーマットのトークンを取得することができます。
Version || Timestamp || IV || CipherText || HMAC- バージョン:0x80固定
- タイムスタンプ:暗号処理を実行した時刻。1970年1月1日UTCから現在までの経過秒数です。
- IV:128ビットの初期化ベクトル。乱数で生成されます。
- 暗号文:暗号文本体。
- HMAC:バージョン,タイムスタンプ,IV,暗号文のSHA256 HMAC。
通常,トークンはいじらずにそのままの保持しておいて,復号もFernetを使えば問題ありませんが,復号処理をFernet以外で行いたい場合は,EncryptionKeyとCipherTextを取り出して,AES128ビットCBCモードであることを伝えて相手に渡せば,相手は復号できることになります。
上の仕様で書いたように,Fernet tokenにはタイムスタンプが含まれています。このタイムスタンプは,Base64をデコードすれば取得することができるため,攻撃者は暗号文は復号できなくても,暗号文が生成された時刻は取得することができます。