Hatena::ブログ(Diary)

かせいさんとこ

2012-03-29

公開鍵暗号について理解が足りていなかったのでメモ

これは何?


github にコミットする時とか、heroku にデプロイする時とか、

認証に公開鍵使うけど、いまいちちゃんと理解していないのでまとめた



目次


  • 暗号化の方法
    • 共通鍵暗号
    • 公開鍵暗号
  • HTTPS
  • SSH
    • 公開鍵認証
    • 具体的な手順

暗号化の方法


共通鍵暗号


信者と受信者が共通の秘密鍵を持って、暗号化と複合を行う

たとえばこんな感じ


平文 : 1234

秘密鍵 : 5678

暗号化 : 1234 x 5678

暗号文 : 7006652

復号化 : 7006652 / 5678


  • 送信者側は、平文を、秘密鍵で暗号化して、暗号文を受信者に送る
  • 受信者は、暗号文を、秘密鍵で復号化して、平文を得る

共通鍵暗号の弱点

  • 最初に鍵を受信者に渡す必要があるが、その時に盗聴されるリスクがある
    • 渡す時暗号化すれば良いけど、その暗号化の鍵を... となる
  • 多人数で秘密の通信をしたい場合、組み合わせの数だけ鍵が必要になる
    • AとB が、Cには秘密の通信をする場合
    • AとC が、Bには秘密の通信をする場合
    • BとC が、Aには秘密の通信をする場合
    • それぞれ鍵が必要になる

公開鍵暗号


公開鍵と、秘密鍵の2つを用意

暗号化には、公開鍵を使って復号には、秘密鍵を使う

公開鍵は暗号化するだけで、復号化できないので、知らない人に渡っても通信の内容がバレることは無い

現在の主流


上記の条件を満たす秘密鍵、公開鍵の作り方はややこしかったので飛ばす

とりあえず、そういうものを使って暗号化していると理解


でも、公開鍵だと一方的な通信しかできないよね?

なので実際の所は、公開鍵を使ってそのセッション限りの共通鍵を渡して、

そのセッションの間だけ、共通鍵暗号で通信するって方法がスタンダードらしい


んでもうちょっと具体的な話

公開鍵暗号が、HTTPSや、SSHでどんな風に使われているかを解説


HTTPS


HTTPが、TLS/SSL で暗号化されている事を示すURLスキーム


TLS/SSL

セキュリティーを要求される通信の為のプロトコル


  1. クライアントは、公開鍵証明書をサーバから受けとる
  2. クライアントは、公開鍵証明書から、公開鍵を取得。それを使って乱数を暗号化してサーバに送る
  3. サーバは、乱数を元にした共通鍵を作って、クライアントに送る
  4. 共通鍵で通信する
  5. 通信が終わったら共通鍵を破棄する

こういう、秘密鍵と共通鍵を組み合わせた方法を、ハイブリッド暗号化方式というらしい


参考

ファイル:SSLによるセキュアな通信.jpg - Wikipedia


公開鍵証明書って?

公開鍵単体では、その公開鍵がどこのものであるかは分からない

なので、以下のような方法で公開鍵を偽って、盗聴することが可能


  1. 悪意のあるC が、Aのものと偽って公開鍵を配布する
  2. それを知らないBが、Cが作った公開鍵で、Aに暗号化情報を送る
  3. Cが、Bの通信を傍受できるならば、通信内容を復号できてしま

そんな問題回避するために、公開鍵の所有者を信頼出来る第三者機関(認証局)が審査して、発行される証明書が、公開鍵証明書

  • んで、認証局が審査をすることで、公開鍵の所有者を保証する仕組みのことを公開鍵基盤(PKI: public key infrastructure)というらしい

証明書の中身

メジャーな証明書の規格、X.509 だと


  • 公開鍵
  • 電子署名(データのハッシュ値を暗号化したものなど。署名の方法によって異なる)
  • 認証局、被認証者の情報など
認証の流れ
  1. 認証局は、秘密鍵(署名用)と、公開鍵(検証用)を用意する
  2. 認証局は、秘密鍵で証明書のデータに署名を行う。この署名を証明書に添付する。
  3. クライアントは、認証局から公開鍵(検証用)を受け取る
  4. 電子署名を公開鍵(検証用)で検証する。
  5. 検証を通れば、その証明書は改ざんされていないので、信用されていると見なせる


参考

電子署名の仕組み 一般財団法人日本情報経済社会推進協会 電子署名・認証センター


認証局の公開鍵はだれが証明するの?

より上位の認証局が認証して、それをそらに上位の認証局が..となっている

なので、最上位の認証局(ルート認証局)は、だれも認証していない

  • 認証局と、被認証者が同一(いわゆるオレオレ証明書)

ルート認証局の情報は予めブラウザに入っており、予め信頼できる認証局と見なされている


参考

電子証明書と認証局


SSH


Secure Shell


暗号や認証の技術を利用して、安全にリモートコンピュータと通信するためのプロトコル

Telnetだと平文でパスワードサーバに送るから危なかっかしい

SSHは、ハイブリッド暗号化方式(上記SSHで言及)で通信するから盗聴されても安心

また、公開鍵を使ったパスワードを使わない認証が可能


公開鍵認証

公開鍵を使った認証方式


  1. クライアントは、秘密鍵(復号用)と、公開鍵(暗号化用)を用意する
  2. クライアントは、サーバに公開鍵(暗号化用)を渡す
  3. サーバで、公開鍵とユーザを結びつける
  4. サーバは、クライアントがログインしてきたら、乱数を生成して公開鍵で暗号化して渡す
  5. クライアントは、乱数を復号してハッシュ値をサーバに渡する
  6. サーバは、クライアントから来たハッシュ値と、自前のハッシュ値を比較して一致したら認証する

これで、鍵ペアがあればパスワードが無くても認証が可能


参考

鍵交換方式による認証


具体的な手順(OpenSSHの場合)


クライアント側

鍵ペアの生成

# rsa, dsa は暗号化の方式
$ ssh-keygen -t rsa -C "コメント"
$ ssh-keygen -t dsa -C "コメント"

rsaで作った場合に生成される鍵

秘密鍵: ~/.ssh/id_rsa

公開鍵: ~/.ssh/id_rsa.pub


サーバ側

ログインしたいサーバに公開鍵を追加する

$ cd ~/.ssh
$ cat id_rsa.pub >> authorized_keys
  • authorized_keys は、信頼している公開鍵の一覧

サーバ側の公開鍵のフィンガープリントをメモしておく

$ ssh-keygen -l
Enter file in which the key is (/Users/xxxxxxxx/.ssh/id_rsa): /Users/xxxxxxxx/.ssh/id_rsa.pub
2048 xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx /users/xxxxxxxx/.ssh/id_rsa.pub (RSA)

クライアント側

ssh を使ってログイン

ssh user@server_name

初回ログイン時に、公開鍵のフィンガープリントの確認が出るので、上記でメモしたフィンガープリントと一致していることを確認

同一のipアドレスでサーバを偽装している場合、フィンガープリントが異なるはず


The authenticity of host 'server_name (xx.xx.xx.xx)' can't be established.
RSA key fingerprint is xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx.
Are you sure you want to continue connecting (yes/no)?

yesを入力すると、~/.ssh/known_host にフィンガープリントが保存されて、

以降、フィンガープリントが異なると警告を出すようになる


参考

入門OpenSSH / 第3章 OpenSSH のしくみ


そんなかんじー

smoking186smoking186 2013/10/20 16:23 186と申します。暗号を生業にしているものです。(あとパンダテーマの作者です)
内容が分かりやすくまとまっていて良いと思いました。
ただ、一点、気になる点があったので、コメントします。

公開鍵証明書―電子署名の説明が(よくある)不適切な説明になっています。

> 1. 認証局は、秘密鍵(暗号化用)と、公開鍵(復号用)を用意する
> 2. 認証局は、証明書のデータをハッシュ化して、そのハッシュ値を秘密鍵で暗号化して、証明書に添付する(これが電子署名)
> 3. クライアントは、認証局から公開鍵(復号用)を受け取る
> 4. 証明書のデータをハッシュ化したものと、電子署名を公開鍵(復号用)で複合したものを比較する
> 5. 一致していたら、その証明書は改ざんされていないので、信用されていると見なせる

この例では「ハッシュ値を秘密鍵で暗号化したもの=署名」となっています。これは良く使われているRSA署名を説明するには十分ですが、そうなっていない電子署名も多々あります。具体例として、DSAがあります(X.509証明書の中でも使われることがある署名方式です)。
この説明の不適切さについては、昔、解説記事を書きましたので、見ていただければと思います。
http://186.hatenablog.com/entry/20080302/1204451511

署名と暗号は違うこともあるという点も踏まえると、

1. 認証局は、秘密鍵(署名用)と、公開鍵(検証用)を用意する
2. 認証局は、秘密鍵で証明書のデータに署名を行う。この署名を証明書に添付する。
3. クライアントは、認証局から公開鍵(検証用)を受け取る
4. 電子署名を公開鍵(検証用)で検証する。
5. 検証を通れば、その証明書は改ざんされていないので、信用されていると見なせる

としていただけませんでしょうか。よろしくお願いいたします。

kasei_sankasei_san 2015/02/13 11:06 Qiitaに引っ越して以降、こちらを放置して居たためコメントに気づかず申し訳ありません...
ご指摘ありがとうございます!
遅まきながら修正しました

白鷺城白鷺城 2017/01/09 22:09 勝手にですが非常に勉強になりました。
ありがとうございます。

kasei_sankasei_san 2017/01/10 10:55 👍

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証

トラックバック - http://d.hatena.ne.jp/kasei_san/20120329/p1