対称鍵暗号または共通鍵暗号は、同じ鍵(またはパスワード)を使ってデータを暗号化および復号します。 これらのアルゴリズムは、他のアルゴリズムと組み合わせて対称鍵暗号方式(例:ChaCha20-Poly1305、AES-128-GCM、AES-256-CTR-HMAC-SHA256)としてよく利用されます。 また、パスワードから鍵を導出する鍵導出アルゴリズム(例:ScryptやArgon2)も使用されます。
対称鍵暗号には、データを固定サイズのブロックで暗号化するブロック暗号と、データをバイトのシーケンスとして暗号化するストリーム暗号の2種類があります。 現代の暗号学で広く使用されている対称鍵暗号アルゴリズムには、AES(AES-128、AES-192、AES-256)、ChaCha20、Twofish、IDEA、Camelliaなどがあります。これらの多くはブロック暗号(例:128ビットの固定サイズのブロックを暗号化)ですが、ストリーム暗号(データをストリームとして1バイトずつ暗号化)もあります。
データを暗号化および復号化するために使用される秘密鍵(共通鍵)は、通常128ビットまたは256ビットのサイズです。 データの送受信には、送信者と受信者の両方が共有鍵を知っている必要があります。 多くのシステムでは、利用者がパスワードを覚えやすいことから、特定のパスワードから秘密鍵を導出するために鍵導出関数が使用されます。
さらに、データの整合性と信頼性を確保するために、暗号化にはメッセージ認証が組み込まれることがあります。 この手法は認証付き暗号化と呼ばれます。
暗号化と復号
入力データが暗号化されると暗号文になり、暗号文が復号されると元の入力データに戻ります。 対称鍵暗号による暗号化と復号には、秘密鍵または鍵を導出するためのパスフレーズが使用されます。 暗号化鍵は16進数またはBase64エンコードされた整数として提供されるか、パスワードから鍵を導出する仕組み(鍵導出)を使用して秘密鍵が生成されます。
対称鍵暗号アルゴリズムは通常、単独で動作することはなく、他の関連する暗号アルゴリズムと連携して対称鍵暗号スキーム/構築を形成します。
一般的に利用されている暗号化スキームでは、暗号化にパスワードと鍵導出アルゴリズム、メッセージ認証コード(認証付き暗号)が組み合わされています。 対称鍵暗号による暗号化の手順には、以下の複数の異なる暗号アルゴリズムが含まれます:
-
鍵導出アルゴリズム (ScryptやArgon2など):
- パスワードのクラックを困難で遅くするために、鍵の代わりにパスワードを使用します
-
ブロック暗号アルゴリズム (AESなど):
- 秘密鍵を使用して固定長のデータブロックを安全に暗号化します
-
暗号利用モード (CBCやCTRなどのブロック暗号モード) + メッセージパディングアルゴリズム (PKCS7):
- AESなどのブロック暗号アルゴリズムを使用して任意のサイズのデータを暗号化します
-
メッセージ認証アルゴリズム (HMACなど):
- 復号後に得られたデータが暗号化前の元のメッセージと一致するかどうかを確認します
ブロック暗号アルゴリズム
対称鍵暗号アルゴリズム(AESのようなもの)は、数学者や暗号屋によって設計されており、暗号化鍵を持たない限り暗号文を復号することが不可能であるという考えに基づいています。 この考え方は、現代の安全な対称鍵暗号アルゴリズム(AESやChaCha20など)に当てはまります。 しかし、DESやRC4などの安全でない対称鍵暗号アルゴリズムについては、この考えに当てはまらない場合があります。
対称鍵暗号アルゴリズムには、AES、ChaCha20、CAST、Twofish、IDEA、Serpent、RC5、RC6、Camellia、ARIAなどがあります。 これらのアルゴリズムは、適切に構成され正しく使用されれば、安全であると考えられています。
AES (Rijndael)
AES(Advanced Encryption Standard、またはRijndaelとしても知られる)は、現代のIT業界で最も人気があり広く利用されている対称鍵暗号アルゴリズムです。 AESが非常に安全で高速、かつ標準化されており、ほとんどすべてのプラットフォームで非常によくサポートされているためです。
AESは128ビットのブロック暗号で、128ビット、192ビット、または256ビットの秘密鍵を使用します。 通常、AES-CTRやAES-GCMのような暗号利用モードで、ストリーミングデータを処理するために使用されます。 ほとんどの暗号利用モードでは、AESの暗号化・復号するときにランダムな128ビットの初期ベクトル(IV、nonce)が必要です。
Rijndaelは、NISTによって主催されたAESコンペティション(1997-2000)で優勝し、DESの次の公式の対称ブロック暗号として「AES」という名前で発表されました。 2001年にAESは米国政府によって公式の推奨事項として採用され、以来重大な脆弱性や攻撃は見つかっていません。
Salsa20 / ChaCha20
Salsa20は、その改良版であるChaCha(ChaCha8、ChaCha12、ChaCha20)およびXSalsa20とともに、著名な暗号学者であるDaniel Bernsteinによって設計された、現代的で高速な対称ストリーム暗号のファミリーです。 Salsa20暗号は、新しい対称ストリーム暗号の設計を目指したeSTREAMコンテストのファイナリストの1つであり(2004-2008)、関連するBLAKEハッシュ関数とともに広く採用されました。 Salsa20およびその派生形はロイヤリティフリーであり、特許は取得されていません。
Salsa20暗号は、入力として128ビットまたは256ビットの対称秘密鍵とランダムに生成された64ビットのノンス(初期ベクトル)を受け取り、無制限の長さのデータストリームを処理して、入力ストリームと同じ長さの暗号化されたデータストリームを出力します。 Salsa20暗号は通常、認証付き暗号を構築するときの1要素として使用されます。実際には ChaCha20-Poly1305 として利用されています。
その他の有名な対称鍵暗号
AESやChaCha20ほど使用頻度は高くないものの、ソフトウェア開発者や情報セキュリティコミュニティで有名な現代の安全な対称鍵暗号には、以下のものがあります。
- Serpent - 鍵サイズ128、192、または256ビットの安全な対称鍵ブロック暗号。パブリックドメインで特許はありません。
- Twofish - 鍵サイズ128、192、または256ビットの安全な対称鍵ブロック暗号。ロイヤリティフリーで特許はありません。
- Camellia - 鍵サイズ128、192、および256ビットの安全な対称鍵ブロック暗号(ブロックサイズ128ビット)。特許取得済みですが、非商用利用には無料です。
- RC5 - 鍵サイズ128から2040ビット、ブロックサイズ32、64、または128ビット、ラウンド数1から255の安全な対称鍵ブロック暗号。ただし短い鍵(56ビット)はブルートフォース攻撃に弱いです。2015年まで特許がありましたが、現在はロイヤリティフリーです。
- RC6 - RC5に似ていますが、より複雑な安全な対称鍵ブロック暗号。鍵サイズ128から2040ビット、ブロックサイズ32、64、または128ビット、ラウンド数1から255。2017年まで特許がありましたが、現在はロイヤリティフリーです。
- IDEA - 鍵サイズ128ビットの安全な対称鍵ブロック暗号。2012年まで特許がありましたが、現在はロイヤリティフリーです。
- CAST(CAST-128 / CAST5およびCAST-256 / CAST6) - 鍵サイズ40から256ビットの安全な対称鍵ブロック暗号ファミリー。商用および非商用利用のためにロイヤリティフリーです。
- ARIA - AESに似た鍵サイズ128、192、または256ビットの安全な対称鍵ブロック暗号。韓国の公式標準で、一般利用には無料です。
- SM4 - AESに似た鍵サイズ128ビットの安全な対称鍵ブロック暗号。中国の公式標準で、一般利用には無料です。
危殆化した対称アルゴリズム
過去には使用されていましたが、現在では危殆化した(破られたアルゴリズム)または議論の余地のあり、使用が推奨されない対象鍵暗号には以下のものがあります。
- DES - 鍵サイズ56ビット、実質的に破られており、総当たり攻撃が可能です。
- 3DES (Triple DES) - 64ビットの暗号であり、破られていると考えられています。
- RC2 - 64ビットの暗号であり、破られていると考えられています。
- RC4 - ストリーム暗号であり、破られており、実用的な攻撃が示されています。
- Blowfish - 古い64ビットの暗号であり、破られており、実用的な攻撃が示されています。
- GOST - ロシアの64ビットブロック暗号であり、議論の余地のあるセキュリティを持ち、リスクがあると考えられています。
メッセージ認証コード (MAC)
AES暗号化アルゴリズムは、パスワードの有効性をチェックするためにMAC(メッセージ認証コード)を使用することがあります。
MACは通常、暗号アルゴリズムの出力(暗号文)に追加で出力されます。 この考え方はAEAD暗号化に関連しています。 MACは、入力メッセージと暗号化鍵から計算されます。 計算されたMACからは入力メッセージや鍵を明らかにすることはできないため、MAC自体は秘密にする必要はありません。 一部のブロック暗号モード(AES-GCMなど)は、メッセージ認証を取得した暗号文の一部として統合しているため、MACを明示的に追加する必要はありません。
通常、MACは次のように計算および使用されます:
- 暗号化の前に、MACは次のように計算されます:
mac = HMAC-SHA256(input_msg, key)
。 - 入力データが暗号化され、暗号文がランダムなソルト(IV)およびMACとともに保存されます。
- 復号化後、MACは再計算され、暗号化されたメッセージとともに保存されたMACと比較されます。
- MACが同じ場合、復号化は成功します:正しい暗号文 + 復号化キー + アルゴリズム設定(IV、暗号利用モード、パディングアルゴリズム)。
- MACが異なる場合、復号化は失敗します:誤ったキー/パスワードまたは壊れた暗号文、誤ったMACまたは異なるアルゴリズム設定(IV、暗号利用モード、パディングなど)。
MACは、暗号化アルゴリズムごとに、別の方法を使って計算および検証することができます。
- Encrypt-then-MAC:暗号化後にMACを計算する。
- Encrypt-and-MAC:暗号化と並行してMACを計算する。
- MAC-then-Encrypt:MACを計算後に暗号化する。
これらの方法は、それぞれ異なるセキュリティ特性と使用シナリオに応じて選択されます。
暗号利用モード
暗号学において、ブロック暗号(例:AES)は、固定サイズ(例:128ビット)のデータブロックを暗号化するように設計されています。 入力ブロックのサイズは通常、暗号化された出力ブロックのサイズと同じであり、キーの長さは異なる場合があります。
一方で、ストリーム暗号は、任意のサイズのデータ(例:PDFドキュメント)を暗号化するように設計されています。これらのデータはストリーム(バイトやフレームのシーケンス、例:ビデオストリーミング)として提供されることがあります。
一般的な対称鍵暗号アルゴリズムのほとんどはブロック暗号ですが、ブロック暗号をストリーム暗号に変換し、任意のサイズのデータを暗号化するためのいくつかのスキームが提案されています。 これらのスキームは暗号利用モードとして知られており、AES、RC6、Camellia、Serpentなどのほとんどのブロック暗号に適用されます。
対称鍵暗号と暗号利用モードは組み合わせて使用され、どのスキームを使っているかは次のように表現します。
- AES-256-GCM:256ビットの暗号化キーとGCM暗号利用モードを持つAES暗号
- AES-128-CTR:128ビットの暗号化キーとCTR暗号利用モードを持つAES暗号
暗号利用モード(CBC、CFB、OFB、CTR、EAX、CCM、GCMなど)は、ブロックよりも大きなデータを安全に暗号化/復号するために、暗号の単一ブロックの暗号化/復号を繰り返し適用します。 一部の暗号利用モード(例:CBC)は、入力をブロックに分割し、最終ブロックにパディング文字を追加し、ブロックサイズに合わせる必要があります。 他の暗号利用モード(例:CTR、CFB、OFB、CCM、EAX、GCM)は、各ステップで平文の一部と内部暗号の状態とのXORを実行するため、パディングは一切必要ありません。
基本的に、大きな入力データを暗号化する方法は次のようになります。復号も同様の流れで行われます。
- 暗号化アルゴリズムの状態を初期化する(暗号化キー+ランダムなソルトを使用)
- 最初のブロック部分を暗号化する。このとき暗号化状態を変換する
- 次のブロック部分を暗号化する。このとき再び暗号化状態を変換する
- 以上の処理を、入力データがすべて処理されるまで続ける
以下の事項は、開発者が暗号利用モードを正しく使用するために知っておくべきことです。
- 一般的に使用される安全な暗号利用モードには、CBC(Cipher Block Chaining)、CTR(Counter)、GCM(Galois/Counter Mode)があり、ランダムな(予測不可能な)初期化ベクトル(IVとも呼ばれる)が必要です。
- Counter (CTR)暗号利用モードは、強力なセキュリティ、パディングなしの任意の入力データ長、並列処理能力のため、ほとんどの場合に適した選択肢です。認証と整合性を提供せず、暗号化のみを行います。
- GCM(Galois/Counter Mode)暗号利用モードは、CTRモードのすべての利点を取り入れ、メッセージ認証コード(暗号メッセージ認証タグを生成)を追加します。GCMは、対称鍵暗号で認証暗号化を実装するための高速で効率的な方法であり、一般的な場合に強く推奨されています。
- CBCモードは固定サイズのブロックで動作します。したがって、入力データをブロックに分割した後、最後のブロックを同じ長さにするためにパディングアルゴリズムを使用する必要があります。ほとんどのアプリケーションでは、PKCS7パディングスキームまたはANSI X.923が使用されます。一部のシナリオでは、CBC暗号利用モードがパディングオラクル攻撃に対して脆弱である可能性があるため、CBCモードを避けることがより良いです。
- ECB(Electronic Codebook)は等しい入力ブロックを等しい出力ブロックとして暗号化します(暗号的攪拌を提供しません)。そのためセキュリティ的に安全ではないため使用しないでください。
- CBC、CTR、GCMなどの暗号利用モードは、ランダムアクセスな復号をサポートしています(例:ビデオプレーヤーで任意の時間オフセットにシークする、暗号化されたビデオストリームを再生するなど)。
CTR (Counter) 暗号利用モード
CTRモード(Counterモード)では、各ブロックで新しい予測不可能なキーストリームブロックが生成されます。これは初期ベクトル(IV、nonceとも呼ばれる)と現在のカウンタ(01、02、03、…)および秘密の暗号化キーに基づいています。 入力ブロックは現在のキーストリームブロックとXORで結合され、出力ブロックが生成されます。
CTRモードでは、入力データの最後の部分が暗号ブロックサイズよりも短くなる場合がありますが、この場合もパディングは必要ありません。入力データ(暗号化前)と出力データ(暗号化後)は常に同じ長さになります。
GCM (Galois/Counter) 暗号利用モード
GCMモードでは、各ブロックごとに増加するカウンタを使用し、処理された各ブロックの後にメッセージ認証タグ(MACコード)を計算します。 最終的な認証タグは最後のブロックから計算されます。
すべてのカウンタモードと同様に、GCMはストリーム暗号として機能するため、暗号化される各ストリームの開始時に異なるIVを使用することが重要です。
初期化ベクトル (IV)
暗号利用モードでは、各暗号化されたメッセージにランダムで予測不可能なIV(ナンス)を使用してください。 同じ対称鍵で複数のメッセージを暗号化する際に、同じIVを再利用するのは間違いです。 再利用すると、ほとんどの暗号利用モードでさまざまな暗号攻撃の可能性が発生します。
なお、IVのサイズは暗号ブロックサイズと同じである必要があります。たとえば、AES、Serpent、Camelliaの場合は128ビットです。
認証付き暗号化
暗号学における認証付き暗号化(AE)とは、データの暗号化と同時に認証コード(認証タグ/MAC)を計算するスキームを指し、メッセージの真正性と整合性を提供するために使用されます。 認証付き暗号化スキームを使用すると、復号化の際に鍵やパスワードが正しいかどうか、また暗号化されたデータが改ざんされていないかどうかを確認できます。
認証付き暗号化(AE)は、関連データを持つ認証付き暗号化(AEAD)とも関連しており、こちらはAEのより安全な改良版です。
AEADは、関連データ(AD)を暗号文とそれが現れるべきコンテキストに結びつけるため、有効な暗号文を別のコンテキストに切り貼りされたことを検出して拒否できます。 AEADは、暗号化されたデータと非暗号化データが一緒に使用されるシナリオ(例:暗号化されたネットワーキングプロトコル)で使用され、データストリーム全体の認証と整合性の保護を保証します。 言い換えれば、AEADは暗号化されていない関連データ(AD)の整合性と真正性をチェックする機能を追加します。
いくつかの暗号化スキーム(ChaCha20-Poly1305やAES-GCMなど)は、認証付き暗号化(AEAD)を提供しますが、他のスキーム(AES-CBCやAES-CTRなど)は、必要に応じて追加の認証を追加する必要があります。
対称鍵暗号スキーム / 構築
暗号屋は、多くの対称鍵暗号スキームを提案しています。最も有名な認証付き暗号(AEAD)スキームの中には、次のものがあります:
-
ChaCha20-Poly1305
- ChaCha20ストリーム暗号と統合されたPoly1305認証子を持つAEAD暗号です。
- 256ビットの鍵とランダムな96ビットのノンスが必要です。
- 極めて高いパフォーマンスを誇り、ほとんどの現代的な暗号ライブラリに実装されています。
-
AES-256-GCM
- AES-GCMはAES(Rijndael)ブロック暗号をGCM暗号利用モードで使用したAEAD暗号です。ストリーム暗号のように振る舞います。
- 256ビットの鍵とランダムな128ビットのノンス(初期ベクトル)が必要です。
- 最も現代的な暗号ライブラリに実装されています。
ほとんどのアプリケーションは、自分自身の暗号化スキームを構築する代わりに、対称鍵暗号のために上記の暗号化スキームを利用することが推奨されます。 これらのスキームは非常に安全であり、証明され、十分にテストされており、暗号ライブラリからすぐに利用できます。
特に、ChaCha20-Poly1305は高性能な暗号であり、モバイルデバイス上において、AES-128-GCMよりも3倍速いため、AES-GCMの代わりに使用することが推奨されています。