【ITニュース解説】How to decrypt broken GCM ciphertext

2025年09月07日に「Dev.to」が公開したITニュース「How to decrypt broken GCM ciphertext」について初心者にもわかりやすいように丁寧に解説しています。

作成日: 更新日:

ITニュース概要

GCM暗号は改ざん防止の認証タグを持ち、破損すると復号が拒否される。しかし、GCMがCTRモードの拡張であることを利用し、認証を強制しない実装や、GCMの初期値とカウンター設定に合わせたCTRモードを使えば、破損GCM暗号文も復号可能だ。

出典: How to decrypt broken GCM ciphertext | Dev.to公開日:

ITニュース解説

GCM暗号化されたデータの復号に関するこの記事は、認証付き暗号という重要な概念と、それが破綻した場合の特殊なケースについて解説している。システムエンジニアを目指す上で、暗号化技術の仕組みを深く理解することは非常に重要だ。

まず、GCM(Galois/Counter Mode)とは、単にデータを暗号化するだけでなく、そのデータの「完全性」と「真正性」も同時に保証する「認証付き暗号」の一種である。データの完全性とは、データが途中で改ざんされていないこと、真正性とは、データが確かに意図した送信元から来たものであることを指す。GCMはこの保証のために「認証タグ」という特別なデータを利用する。認証タグは、暗号化されたデータ(暗号文)に対して、特定の鍵を使って計算されるハッシュ値のようなもので、例えるなら、宅配便の中身が改ざんされていないかを証明する「封印シール」のような役割を果たす。

もし何らかの理由で暗号文が途中で壊れたり、悪意のある第三者によって改ざんされたりした場合、その認証タグは元の暗号文と一致しなくなる。この「封印シール」が破れている状態になると、多くの暗号ライブラリは、セキュリティ上の理由からそのデータの復号を拒否する。これは非常に賢明な判断だ。なぜなら、認証付き暗号の目的は、まさにデータの改ざんを不可能にすることにあるからだ。もし認証タグが無効であるにもかかわらず復号を許してしまうと、改ざんされたデータがそのまま使われてしまい、深刻なセキュリティ問題につながる可能性がある。開発者にとっては、認証の有無を自分で判断する必要がなくなり、認証が必須であると決められている方が、かえって間違いが起こりにくいというメリットもある。

しかし、記事では、特定の状況下で「認証が破れていても、とにかくデータの内容を取り出したい」という特殊な要望がある場合について述べている。このような場合、大きく二つのアプローチが考えられる。一つは、OpenSSLのように、認証タグの検証を強制しないGCM実装を選択することだ。そしてもう一つ、この記事が焦点を当てているのが、GCM暗号文を「CTR(Counter Mode)モード」で復号するという方法である。この方法は、GCMとCTRの内部構造に関する深い理解を促すため、特に興味深いとされている。

CTRモードは、ブロック暗号(例えばAES)をストリーム暗号のように扱うための運用モードの一つだ。その基本的な仕組みは比較的シンプルである。まず、「カウンタブロック」と呼ばれる、毎回異なる一連のユニークなブロック群を生成する。次に、これらのカウンタブロックを暗号化鍵で暗号化し、「キーストリーム」と呼ばれる疑似乱数のようなデータを生成する。そして、このキーストリームと平文(暗号化の場合)または暗号文(復号の場合)を、ビットごとの排他的論理和(XOR)演算で組み合わせることで、データの暗号化・復号を行う。CTRモードの最大の特徴は、暗号化と復号に全く同じ処理が使える点にある。

CTRモードの仕様は、カウンタブロックの生成方法について比較的自由度が高いが、一般的には「標準インクリメンティング関数」と呼ばれる方法が推奨されている。これは、初期のカウンタブロックを決め、そのブロックの一部を「カウンタ」として扱い、整数を数えるように順に増加させていく方法だ。例えば、128ビットのブロックのうち下位32ビットをカウンタとして使用する場合、この32ビットの値を0から順に1ずつ増やしていく。カウンタが最大値に達すると、次に0に戻る、つまり「ラップアラウンド」する。記事では、具体的な16進数表記のカウンタブロックの例を挙げており、下位4バイト(32ビット)が順に増えていく様子が示されている。

GCMモードは、このCTRモードをベースにしながら、いくつかの点でより具体的な規定を加えたものと言える。つまり、GCMはCTRモードの特定の運用形態に認証タグの概念を追加した、より厳格なバージョンなのだ。GCMとCTRの主な違いは以下の3点にある。まず、ブロックサイズについて、CTRでは任意だが、GCMでは128ビットと固定されている。次に、カウンタのインクリメンティング関数について、GCMでは標準インクリメンティング関数が必須であり、かつカウンタ長も32ビットに固定されている。そして最後に、初期カウンタブロックの生成方法である。CTRでは自由に選べるのに対し、GCMでは「初期化ベクトル(IV)」という入力に基づいて、最初のカウンタブロックを生成する特定のアルゴリズムが定められている。特に、96ビットのIVを使用する場合が最も一般的で、この場合、最初のカウンタブロックは「IVのデータと、その後ろに続く16進数の00000002という固定値」を結合したものとして生成される。

これらのGCMとCTRの内部構造の比較を踏まえると、認証が破綻したGCM暗号文をCTRモードで復号する道筋が見えてくる。特に、GCMが96ビットのIVを使っている場合に限られるが、このケースでは、CTRモードで復号する際に、GCMが使用するのと同じカウンタブロック生成規則をCTRに適用すればよい。具体的には、CTRモードのパラメータとして、標準インクリメンティング関数を使用し、カウンタ長を32ビットに設定し、そして初期カウンタブロックとしてGCMのIVと固定値「00000002」を結合したものを与えるのだ。

記事では、Web Crypto APIを使ったこのアイデアの検証についても触れている。Web Crypto APIはCTRとGCMの両方を実装しており、CTRモードでは標準インクリメンティング関数を使っているため、適切なカウンタ長と初期カウンタブロックを設定するだけでテストが可能である。実際に試してみると、GCMで暗号化されたデータがCTRモードで復号できることが確認できる。ただし、ここで一つ重要な注意点がある。GCMは暗号文の末尾に認証タグを追加して保存するため、CTRモードで復号すると、元の平文に加えて、その認証タグの部分も「復号」されてしまい、結果として「意味のないゴミデータ」として出力されることになる。これは、CTRモードが認証タグを通常の暗号文の一部として扱い、純粋にXOR演算で処理した結果である。

このように、GCMとCTRの内部的な共通点と相違点を理解することで、通常では復号できないはずの、認証が破綻したGCM暗号文の内容を、あくまでデータとして取り出すことが可能になる。これはセキュリティ上の推奨される運用ではないが、暗号技術の仕組みを深く理解するための貴重な洞察を与えてくれるものだ。

関連コンテンツ

関連ITニュース

【ITニュース解説】How to decrypt broken GCM ciphertext | いっしー@Webエンジニア