クラウド同上

Cloud KMS、鍵ローテーションの嘘/ホント

Author
かめなし
Lv:7 Exp:5669

2017年12月より現職。SREエンジニア目指してIaC、Kubernetesを勉強中。好きな言語はJavascript。好きなGCPプロダクトはCloud Build。好きなOCGカードは《破壊剣士融合》。

お久しぶりです。春はメランコリックなクラウドエースSREチームの亀梨です。

Cloud KMS(Key Management Service)について、「鍵のローテーションをしてしまったら、古い鍵で暗号化してしまったファイルは元に戻せないのではないのか?だから、ローテーションなんてしないほうがいいのでは。」という意見を耳にしました。

『暗号鍵のローテーション』という機能をGCPがmanagedで出している」以上、「人間が頑張って手動で『鍵』と『それを使った暗号化済ファイル』の対応付けを頑張らないといけない」なんて事は考えられないので、この記事ではそれを実証しようと思います。

っていうかドキュメントに「ローテ前の鍵で暗号化したファイルは、ローテ以後もちゃんと戻せる」って書いてあるんですけどね。(TL;DR)

鍵をローテーションしても、以前の鍵バージョンが無効になったり破棄されたりすることはありません。以前の鍵バージョンはメインではなくなりますが、引き続きデータの復号に使用できます。

https://cloud.google.com/kms/docs/key-rotation?hl=ja

Cloud KMSとは

ひとことで言うなれば、『IAMでの権限付与』に基いて、『暗号鍵へのアクセス権を管理』できるサービスです。

その鍵を保有・管理する主体をGCP(Google Cloud Platform)が提供するため、鍵の運用をする必要がありません。

他のIAMに権限を依拠するサービスと同様、Googleアカウント( G Suite / Gmail / Cloud Identity )で認証し、API経由で暗号化/復号/鍵の管理を提供します。

応用としてはkubesecとか、みんな大好きTerraform GCP Providerで動的に秘匿情報を復号したりできます。

そして、それをすることができるアカウントをIAMで管理できます。Service Accountにも当然付与できます。

そもそも鍵のローテーションは何のためにあるのか

現状、一般的に商用で普及している仕組みとして、「計算コストの安さ・移植の容易さ・突破されにくさ」のバランスに秀でた暗号化方式のRSA暗号を用いた公開鍵基盤があります。

いくら巨大な数の素因数分解が困難であったとしても、たとえば、 /etc/shadow ファイルを盗まれるとか。通信経路上でTLS通信パケットを継続的にキャプチャされるとか。暗号化したけど権限管理がいいかげんで全世界に公開されている機密ファイル…等は、総当たり攻撃でいつかは破られる運命にあります。(やる人が居るとは言っていない)

SSH等でも、通信の途中で鍵をどんどんローテーションし、「ある時点まではこの鍵で暗号化していたけれど、この時点からは別の鍵で暗号化するんで、別の鍵で復元してね」をやっています。

これにより、ある鍵が割れたとしても、平文へのアクセスが部分的にしか得られないというメリットがあります。

暗号鍵の賞味期限

「サーバ証明書」を運用したことがあるでしょうか。

なぜ、あんな短いスパンで更新しなければならないのか。それは、前述の通り「賞味期限が切れてバレバレになるおそれがあるから」です。

認証局が豪遊するためではないのです。たぶん。

ローテをしないことによるデメリット

は、もう書いてしまいましたね。次に行きましょう。

鍵バレした!ので、古い鍵で戻せなくしたい。

首題と真逆のケースになりますが、たとえば「現在使っている鍵バージョンを用いて不正な操作が行われた」ことをCloud Audit Loggingで検出したりした場合、古い鍵バージョンを無効化し、新しい鍵へローテーションすることができます。

不正な操作に使用されたアカウントを特定・排除したのち、新バージョンの鍵を用いて暗号化し直すことで、(古い鍵で暗号化していたファイルは助からなくても)それ以降の鍵で暗号化したファイルへのアクセスを防ぐことができます。


で、ローテをしたら戻せない、は本当なのか?

やってみましょ。

以下のステップで進めます。

  1. 平文を用意する
  2. Cloud KMS KeyRingを用意する
  3. KeyRing内のKeyを用意する
  4. 現在のKeyバージョンを確認する
  5. 現在のKeyを用いて、暗号化と復号ができることを確認する
  6. Keyを手動ローテーションする
  7. ローテーション後、旧鍵で暗号化したファイルが復号できることを確認する
  8. 旧鍵を破棄した後、新鍵で旧鍵前提の暗号化済ファイルが復号できないことを確認する

平文を用意する

各プロジェクトのCloud Console右上にあるCloud Shellを起動します。

cloud shell起動ボタン

お好きなエディタで、平文のファイルを作りましょう。

$ vim choyugo.txt
$ cat choyugo.txt
《超融合/Super Polymerization》
速攻魔法(準制限カード)
このカードの発動に対して魔法・罠・モンスターの効果は発動できない。
(1):手札を1枚捨てて発動できる。
自分・相手フィールドから、融合モンスターカードによって決められた融合素材モンスターを墓地へ送り、
その融合モンスター1体をEXデッキから融合召喚する。

Cloud KMS KeyRingを用意する

Cloud Console > 「三(ハンバーガーメニュー)」 > IAMと管理 > 暗号鍵と辿ります。

「キーリングを作成」しましょう。

キーリング「team5ds」がリージョン「asia-northeast1」に作成されました。

KeyRing内のKeyを用意する

team5dsという鍵束の単位で管理されるメンバーである鍵を作成します。

いったんデフォルトのローテ期間「90日」で作成するものとします。

※「暗号化/復号」とそれ以外の表記に揺れがあるのは私共の不徳の致すところであり、サービス提供側へfeedback依頼を上げておきます故ご容赦ください。

現在のKeyバージョンを確認する

作成された「chokan」キーを確認します。

概要画面から以下のような操作が可能です。

「名前」列の「chokan」リンクを辿り、鍵のバージョン画面へ遷移します。

バージョン「1」の「chokan」のみが存在していることがわかります。

現在のKeyを用いて、暗号化と復号ができることを確認する

暗号化してみます。

$ gcloud kms encrypt --project ca-kmnn-test --location asia-northeast1 --keyring team5ds --key chokan --plaintext-file ./choyugo.txt --ciphertext-file ./choyugo-enc-v1.enc

$ ls -lh
total 8.0K
-rw-r--r-- 1 kamenashi kamenashi 530 Apr  3 15:39 choyugo-enc-v1.enc
-rw-r--r-- 1 kamenashi kamenashi 447 Apr  3 15:06 choyugo.txt

$ file choyugo.txt
choyugo.txt: UTF-8 Unicode text

$ file choyugo-enc-v1.enc
choyugo-enc-v1.enc: data

暗号化できたことがわかります。

復号してみます。

$ gcloud kms decrypt --project ca-kmnn-test --location asia-northeast1 --keyring team5ds --key chokan --plaintext-file ./choyugo-plain.txt --ciphertext-file ./choyugo-enc-v1.enc

$ ls -lh
total 12K
-rw-r--r-- 1 kamenashi kamenashi 530 Apr  3 15:39 choyugo-enc-v1.enc
-rw-r--r-- 1 kamenashi kamenashi 447 Apr  3 15:42 choyugo-plain.txt
-rw-r--r-- 1 kamenashi kamenashi 447 Apr  3 15:06 choyugo.txt

$ cmp choyugo.txt choyugo-plain.txt ; echo $?
0

できましたね。

これでkeyring team5ds にアクセス権を持つ人は、choyugo-enc-v1.enc をいつでも復号できることになります。

Keyを手動ローテーションする

します。

やりました。

「メインのバージョン」が「2」になりました。しかし、依然として「1」も「有効」です。

ローテーション後、旧鍵で暗号化したファイルが復号できることを確認する

いよいよ本題です。「メインのバージョン」が「2」を指しているとき、勝手に「1」を使って復号してくれるのでしょうか?

$ gcloud kms decrypt --project ca-kmnn-test --location asia-northeast1 --keyring team5ds --key chokan --plaintext-file ./choyugo-plain-v2main.txt --ciphertext-file ./choyugo-enc-v1.enc

$ cmp choyugo.txt choyugo-plain-v2main.txt ; echo $?
0

はい、できちゃいました。

驚きですね。一体どこに「どの鍵バージョンを使ったか」の情報を保持して判断しているんでしょうか。読者の皆様のご想像にお任せいたします。

$ strings choyugo-enc-v1.enc | grep team5ds
$ 

少なくとも平文でヘッダに格納されているわけではないようです。

旧鍵を破棄した後、新鍵で旧鍵前提の暗号化済ファイルが復号できないことを確認する

「破棄」と「無効化」があるので、まずは「無効化」してみます。

「あとで再度有効化」できること、「無効にしてから、本当に無効になるまでの遅延期間が最長、数時間存在する」旨の但し書きが表示されます。

無効になりました。

さて、遅延が最長、数時間あるという事なので、数分しか経っていない現時点では戻せてしまうかもしれません。

えいやっ。

$ ls -lh
total 16K
-rw-r--r-- 1 kamenashi kamenashi 530 Apr  3 15:39 choyugo-enc-v1.enc
-rw-r--r-- 1 kamenashi kamenashi 447 Apr  3 15:42 choyugo-plain.txt
-rw-r--r-- 1 kamenashi kamenashi 447 Apr  3 15:50 choyugo-plain-v2main.txt
-rw-r--r-- 1 kamenashi kamenashi 447 Apr  3 15:06 choyugo.txt

$ gcloud kms decrypt --project ca-kmnn-test --location asia-northeast1 --keyring team5ds --key chokan --plaintext-file ./choyugo-plain-v2main-v1disabled.txt --ciphertext-file ./choyugo-enc-v1.enc
ERROR: (gcloud.kms.decrypt) FAILED_PRECONDITION: The request cannot be fulfilled. Resource projects/ca-kmnn-test/locations/asia-northeast1/keyRings/team5ds/cryptoKeys/chokan/cryptoKeyVersions/1 has crypto_key_version.state: DISABLED, but ENABLED is required.

$ date
Wed Apr  3 16:03:32 +09 2019

ちゃんとFAILED_PRECONDITIONで鍵がDISABLEDなエラーを返してくれました。機能していますね。

ということで、「鍵を破棄したり無効化することで、旧バージョン鍵で暗号化したファイルを復元できなくする」ことができることが実証できました。

おわりに

いかがでしたでしょうか。

クラウドエース株式会社では、可能な限りmanagedな運用を提供するGoogle Cloud Platform(GCP)を用いてDevOps、NoOps、IaCを推進するSREチームだけでなく、アプリケーション開発、G Suite導入支援といった様々な技術を扱っております。

Terraformが好きな方も、Pulumiが好きな方も、Magic: the Gathering、遊戯王OCG、スマブラ、サッカーが好きな方、様々なエンジニアが働くクラウドエースで、一緒にお仕事したい方を募集しております。

私の推しOCGカードは「超融合」です。

ご応募はこちらからどうぞ。

次の記事を読み込んでいます
次の記事を読み込んでいます
次の記事を読み込んでいます