これは何?
HTTPS通信に使われる証明書について調べたことをまとめました。
そもそも証明書はなぜ必要なのか?
コメント欄でangel_p_57さんにいろいろ教えていただいたので間違ってそうな部分を取り消し線で入れていきます。
(取り消し線入れたほうが同じような勘違いをしている人に伝わりやすそうなので)
実は理解されていないSSL証明書の役割を引用して修正していく。
証明書を使う目的として
-
通信の暗号化→証明書なしでも暗号化は可能 -
Webサイトの運営者の実在性を証明すること→サイトの運営組織情報の提供が目的であって,実在性を証明するのは目的でない
の2つが大きな目的。
通信が暗号化されていない場合,攻撃者により通信が盗聴されると,決済情報やパスワード等が窃盗される恐れがある。
また,サイトの運営者の実在性を保証することでフィッシング用の偽サイトとの見分けがつく。
証明書を使う目的はサーバ認証である。
ただ、「認証」という日本語は色んな意味を持っている、というより色んな言葉の訳語として無節操に割り当てられていて、それ自身誤解されやすいアレな面もあって。なので言葉を替えると「本人確認」となる。
※対象がサーバなので「人」ではないけど、他に適当な言葉もないので、悪しからず。
つまり、twitter.com のサイトで使っている証明書であれば、「このサイトは twitter.com で、確かに本物です」ということを証明する役割を持つ。なんのことはない、運転免許証やパスポートと同じ身分証と同じことだ。
RFC2246にも以下のような記載がある。
certificate
As part of the X.509 protocol (a.k.a. ISO Authentication framework), certificates are assigned by a trusted Certificate Authority and provide a strong binding between a party's identity or some other attributes and its public key.
つまり,公開鍵とドメインの結びつきを保証するのが証明書を使う目的である。
まず,デジタル署名より始めよ
証明書について知る前にまず,基盤となるデジタル署名という技術の理解が必要だと思う。
デジタル署名の足りない部分を補うための技術が証明書なので
RFC3126によるとデジタル署名は以下のように定義されている。
The European Directive on a community framework for Electronic Signatures defines an electronic signature as: "data in electronic form which is attached to or logically associated with other electronic data and which serves as a method of authentication".
直訳すると「他の電子データに添付され、または論理的に関連付けられ、認証方法として機能する電子形式のデータ」である。
また,同ドキュメントには以下のような記述がある。
An electronic signature produced in accordance with this document provides evidence that can be processed to get confidence that some commitment has been explicitly endorsed under a signature policy, at a given time, by a signer under an identifier, e.g., a name or a pseudonym, and optionally a role.
つまり,デジタル署名の目的とはある電子ドキュメントを認証することが目的と言えるのではないだろうか。
これを実現するために,デジタル署名では公開鍵暗号方式を使用して改ざんの検知を行う仕組みがある。
- 送信者が公開鍵,秘密鍵を生成。
- 送信者が公開鍵を送信する。
- 送信者はデジタル署名を作成する。秘密鍵を使ってメッセージ(デジタル証明書なら本人情報)のハッシュを暗号化する。
- 送信者はデジタル署名とメッセージを送信する。
- 受信者は受信した公開鍵によってデジタル署名を復号し,メッセージのハッシュ値と比較することで改ざんを検知する。
つまり,デジタル署名を複合できるということは,公開鍵を作成したのと同じ人物がコンテンツを作成したことが確認できる。
また,複合したメッセージのハッシュを用いてメッセージの改ざん検知ができる。
opensslコマンドで実際に試せるのでやってみる
mkdir digital_certificate
cd digital_certificate
# 秘密鍵と公開鍵を作成
openssl genrsa -out private_key.pem 2048
Generating RSA private key, 2048 bit long modulus (2 primes)
..........................+++++
..............................................................+++++
openssl rsa -in private_key.pem -pubout -out public_key.pem
# コンテンツ(test.txt)を作ってデジタル署名を作成する
cat <<EOF > test.txt
heredoc> sigma
heredoc> EOF
cat test.txt
sigma
openssl dgst -sha256 -sign private_key.pem -out signature.bin test.txt
# 署名の検証
openssl dgst -sha256 -verify public_key.pem -signature signature.bin test.txt
Verified OK
試しにtest.txtを変更してみると署名の検証が失敗することがわかる。
# test.txtを編集
sed 's/sigma/hoge/g' test.txt > test.txt
# 署名の検証が失敗する
openssl dgst -sha256 -verify public_key.pem -signature signature.bin test.txt
Verification Failure
一応手動でハッシュを比較してみる
署名の検証部分が気になったので手動で検証試してみる。
公開鍵でデジタル署名を複合してもバイナリになっているため,バイナリ同士で比較する必要がありそう。
# デジタル署名を公開鍵で複合
openssl rsautl -verify -inkey public_key.pem -pubin -in signature.bin -out decrypted_hash.bin
# 元データのハッシュを取得
openssl dgst -sha256 -binary test.txt > original_hash.bin
# ハッシュを比較(デコードした署名の32文字目以降がハッシュらしい)
tail -c 32 decrypted_hash.bin 1
#�M��5�
�oy��
�O�Ȉ6aZ+��r��)�%
cat original_hash.bin
#�M��5�
�oy��
�O�Ȉ6aZ+��r��)�%
デジタル署名だけでは足りない部分
公開鍵,秘密鍵の発行者とメッセージの送信者が同じことはデジタル署名を使えば確認できる。
しかし,公開鍵を発行した人間が誰なのかはわからない(本人確認できない)
実際にやりとりをしたい人をAさんとした時,
Aさんが送信したメッセージや公開鍵を攻撃者が取得し,自身が作成した公開鍵にすりかえられたとしても,受信者が確認できるのは攻撃者が作成した公開鍵を使って検証するため改ざんに気づくことができないのだ(中間者攻撃)。
この問題を解消するため,送信者が本物であることを確かめる必要がでてくる。
これを解決するための技術がデジタル証明書(通称: 証明書)である。
次回
デジタル証明書について解説する