Amazon EC2のキーペア生成について、本来あるべき形

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

よく訓練されたアップル信者、都元です。EC2の世界にはキーペアという登録エンティティがあります。EC2サーバにSSH接続するための鍵 *1としての働きを持ちます。

暗号技術のおさらい

突然ですが、暗号の世界の技術を大きく3つとりあげ、簡単に整理しておきましょう。私の説明は正確ではないと思いますので、あわせてWikipediaあたりの説明もご参考に。

  • 暗号:情報のヒミツを守る。詳しくは → 暗号 - Wikipedia
  • 電子署名:ある文章を、ある人が認めた状態から改ざんされていないことを確認する。詳しくは → 電子署名 - Wikipedia
  • 認証:通信の相手が、想定した本人であること(正当性)を確認する。詳しくは → 認証 - Wikipedia

一般的に暗号というと思い浮かべるものは「共通鍵暗号方式」でしょう。代表的なところでは暗号化zipでしょうか。暗号化時と復号化時に同じパスワードを使います。一方「公開鍵暗号方式」というものがあります。こちらは多くの一般の人達にはあまり馴染みが無い *2ものかと思いますが、先日非常に分かりやすい説明を見つけましたのでご紹介しておきます。 → 妻に公開鍵暗号を教えてみた - 西尾泰和のはてなダイアリー

この西尾さんの説明を読むと「電子署名」まで理解できます。

続いて「認証」ですが、これも共通鍵を使って行う認証と、公開鍵を使って行う認証があります。多くのWebサービス等にログインする際にパスワードを入力する、というのが共通鍵認証ですね。しかし、EC2インスタンスにSSH接続する際は、パスワードを使いません。pemというよくわからないランダム文字列が書き込まれたファイルを使いますね。

この認証では、「SSH接続時に、クライアントがpemファイルの内容をEC2に送りつけて、EC2が持っている内容と一致しているかどうか」を検証しているわけではありません。EC2側は、pemファイルの内容を知りません。pemファイルは秘密鍵であり、EC2側が知っているのはそれに対応する公開鍵のみです。ざっくり *3と説明すると、以下のような手順を踏んでいます。

  1. クライアントからサーバにSSH接続要求を行う。
  2. 接続要求受けたサーバは「適当なランダムデータ」を生成し、公開鍵を使ってそのデータを暗号化してクライアントに送る。
  3. 暗号文を受け取ったクライアントは、自身の秘密鍵でそのデータを復号化し、それをさらにサーバに送り返す。
  4. サーバは先ほど生成した「適当なランダムデータ」と、クライアントが復号化したデータを比較する。

この暗号文を復号化できるのは本人だけであるはずなので、データが一致すれば認証が通るというわけです。これが、公開鍵認証です。

公開鍵認証

以上のように、公開鍵認証技術は公開鍵暗号技術をベースとしています。公開鍵暗号は、公開鍵と秘密鍵という鍵のペアがあり、知識の非対称性が特徴です。

仮に、EC2でデフォルトのSSH認証方式が公開鍵方式ではなく共通鍵方式であったとします。その場合、共通鍵であるパスワードは、我々がAWSに対して登録(=通知)するか、もしくはAWSがランダムで生成したものを我々に通知することになるでしょう。つまり、我々ユーザの他に、AWSもパスワードを知っているわけで、(そんなことは無いだろうけど)AWSもOSにログインする権限を持ってしまっている、という事になってしまいます。

AWSの共有責任モデルでは、OSは我々ユーザの責任において管理する部分であり、AWSがログインする権限を持つべきではない部分です。

ここに公開鍵認証方式が導入されていることにより、AWS側が知る必要があるのは公開鍵だけであることになり、秘密鍵はユーザだけが知っている情報であることが保証されます。

キーペアの生成

ところで、皆さんはキーペアをどのように作成していますでしょうか。EC2の管理コンソールで「Create Key Pair」の機能使って生成を行い、秘密鍵をダウンロードしているのではないでしょうか。

2014-08-29_1652

厳密に厳密に考えると、この方式は良くないことが分かります。AWSからダウンロードするということは、AWSが秘密鍵を知ってしまう可能性がある、ということです。もちろん、実際は保存などせず、即座に破棄しているはずです。細かくは追っていませんが、もしかしたらローカル(Javascriptの世界)で生成しているかもしれません。

きちんと秘密鍵を守るには、キーペアはローカルマシン上で生成し、公開鍵のみをAWSに通知するべきです。鍵の生成は以下のとおり、ssh-keygenコマンドで可能です。この場合hoge.pemが秘密鍵、hoge.pem.pubが公開鍵として生成されます。

$ ssh-keygen -t rsa -f hoge.pem
Generating public/private rsa key pair.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in hoge.pem.
Your public key has been saved in hoge.pem.pub.
The key fingerprint is:
00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00 classmethod@example.com
The key's randomart image is:
+--[ RSA 2048]----+
|                 |
|                 |
|                 |
|                 |
|                 |
|                 |
|                 |
|                 |
|                 |
+-----------------+
[~]$ cat hoge.pem
-----BEGIN RSA PRIVATE KEY-----
(略)
-----END RSA PRIVATE KEY-----
$ cat hoge.pem.pub
ssh-rsa AAAA(略)8pzk5 classmethod@example.com

この公開鍵をAWSに登録するためには「Import Key Pair」ボタンを使うわけですね。

2014-08-29_1703

まとめ

AWSの管理コンソールがキーペアの「生成」機能を持っているのは、利用者の利便性を確保するためです。また、上では触れませんでしたが、Windowsサーバのパスワード復号化時に管理コンソールに鍵を入力させるUIもあります。これも利便性確保のための機能 *4であり、本来は「暗号文をローカルマシン内で復号化すべき」です。

しかし、本来あるべき姿として、上記のようにローカルマシン上で鍵生成を行い、必要の無い鍵漏洩の可能性を排除できる、ということを覚えておくと言いかもしれません。

脚注

  1. Windowsインスタンスであれば、AWSが暗号化した状態で我々が受け取る「Administratorのパスワード」を復号する鍵。
  2. 理解されていない。が、知らずに使ってはいる。
  3. つまり、正確にはなにか細かい間違い・違いがあるかもしれませんので注意。
  4. 実際、Windowsのパスワード復号化時に、ブラウザはAWSと通信をしていないはずです。