しいしせねっとわーくWEBCASメール配信システム
[技術資料室] [ネットワーク編] [Linuxメモ] [Javaのsecurity]
[SSHメモ] [OpenSSL] [スマートカード]

暗号通信のしくみ
SSL/TLS/PKIメモ

なんとなくSSLとPKIとやらについて、分離できないままつらつらと書いています。最近なんとなくわかってきましたよ。ファイルを分解してみるところまで、進めてみたい。

公開鍵的項目と共通鍵的項目を分けた方がいいような気がしてきた。

通信とセキュリティ

いろいろ、個人情報などを送信する機会なども増えてきた。昔の通信なら相手と直接やりとりできていたが、インターネットでは他の人にだまされないだろうか、そんな不安もあったりなかったり、それを解消するのが公開鍵基盤といわれる公開鍵基盤PKIやSSL/TLSなどのしくみなのです。

どんな感じで必要になって、どんな感じで作られて行ったのかを見てみましょうかということかな。

暗号の様々な種類

現在使われている暗号化の仕組みにも、いろいろなものがあります。

上位的なまとまり

中間的なもの

下の方の仕組み

基本的なところは共通鍵暗号、公開鍵暗号、ハッシュ関数の組み合わせで出来上がっています。

SSL/TLSの基礎知識? 暗号と証明

SSL(Secure Socket Layer)は、World Wide Webの暗号化などに使われていますが、これはなにかというと、PKI(Public Key Infrastructure、公開鍵基盤)という相手証明と暗号化の2つをTCP上で実現するものです。SSLとTLSは機能としては同じものです。単純に暗号化するだけでは、相手が違う場合に盗聴されてしまうため、データを暗号化して情報が漏れたり改変されたりしないようにする役割のほかにも、相手が誰であるかを証明するという役割が必要になるのです。ひとつは住民票、運転免許のような役割で相手を確認します。相手を確認した後、データを暗号化しながら他の人に読まれないように暗号化された通信をします。

SSL/TLSではTCPの上に相手を認証したり暗号化する層をつくることで、安全性を確保しています。相手がわかっただけでも、暗号化されただけでもじゅうぶんではありません。

  1. 相手を確認する (なりすまし、オレオレ詐欺などの防止)
  2. 暗号化する (盗聴、改変の防止)

まずは公開鍵基盤(PKI)という相手を信頼する手段があり、その上にSSL/TLSが成り立っている、というようなものでしょうか。

SSL/TLSで通信できるのは、標準的なTCP/IPの中なので、直接繋がるブラウザ(等のソフト)とサーバ、1対1の関係だけです。電子メールのように、相手と直接やりとりせず時間がずれたりする場合、複数の間でやりとりする場合などには、S/MIMEなどの少し違った方法があります。これも、基礎的なところはPKIを使っているので同じで、相手の確認、暗号化方法などが異なります。

PKIの仕組みはRSA社かVeriSignかな? SSLはNetscape社が開発したものだったりします。SSLはその後TLS(Transport Layer Security)としてSSL v3を修正したものがIETFで標準化され RFC 2246に、TLS 1.1が RFC 4346 になっています。機能はTLSが使われることが多いようですが、用語としてはSSLのほうがまだまだ一般的なようです。

参考

PKI(Public Key Infrastructure 公開鍵基盤)のしくみと信頼性の基礎知識

SSL/TLSなどでは単純に暗号化した通信をしているだけと思われがちですが、相手のサーバを管理している組織が、どのような存在なのかを証明するという役割があります。そこんとこ見てみましょう。

PKIは、秘密鍵(私有鍵ともいう)と公開鍵、(証明書も?)を使って相手を確認したり、データ暗号化する手段です。電子データを扱うときに、公開鍵を免許証、会員証、(名刺?)などのかわりに本人を証明するものとして使います。そのため、SSHなどは秘密鍵、公開鍵がありますが、SSL/TLSでは相手が不特定の場合が多いため、公開鍵は公開鍵証明書という名前などの証明付きの形になっています。

証明書でデータをくるむことで、通信相手が証明書に書かれた企業や個人であるということが確認できるようになっています。

免許や会員証に発行元があるように、証明書にも発行元があります。そこが名前などを(住民票や登記簿などで)確認して証明書に記載、署名しているため、偽装できにくくなっています。

このためにVeriSignなどに高い金払ってるんだったりしますね。最近は安いところもありますが、信用度はどうかな。

  1. CA(認証局 VeriSignなど)が、サーバ管理組織の存在を何かの証明書などで確認し、電子証明書を発行する。
  2. 電子証明書は存在を確認した上で発行され、秘密鍵と対でしか使えないので、その組織がネットワーク上の通信相手という証明になる。本人確認方法によっては会員証程度の証明能力しか持たない。

PKIが利用できるのは、WebなどのSSL通信の他に、電子メール(S/MIME?)などもあります。

SSLやS/MIMEなどPKIを素にしているものには、暗号化と署名(証明)という2つの役割があります。SSLとS/MIME、PKI自体の暗号化は少しだけ方法が違うようです。

セキュリティ向上の一部ですが、SSLやPKIさえ使っていれば安全、というわけではありません。その他の対応もセキュリティの向上には必要です。

PKIの理想と現実

まず現実では、Webサーバの証明書発行機関(CA)から証明書が発行されています。これは、何の意味があるのでしょうか?

CAは、実在する企業や個人の証明書と対応する形で電子証明書を発行しているだけです。たまたまWebブラウザに最初からCAの証明書が入っているので、利用する人も多いだけです。

でもこれは何か間違っています。元の証明書(紙)を発行していた機関が電子証明書も発行すれば何の問題もないはずです。

難しいからしていないだけではないでしょうか? 認証局が発行していると、企業がどのグループに所属しているのか等々の証明が難しくなります。階層化できていないのです。個人の運営するサーバなら、住基カードで署名できてもいいはずです。

でもまだ、使いやすいソフトもないので、この方法はおすすめできないかもしれません。

秘密鍵(私有鍵/Private Key)/公開鍵(Public Key)

秘密鍵と公開鍵は、この2つを組み合わせることで通信情報を暗号化したり、中身が改変されていないことを証明したりするものです。

秘密鍵   公開鍵 どういうことか?
署名

誰でも読める

○秘密鍵所有者が作ったデータが改変されていないという証明をつける。印鑑やサインのようなもの
読める 暗号化 ○秘密鍵所有者しか読めない。盗聴防止
  署名 ×誰でも署名できるものに署名しても意味がない
暗号化 解読 ×公開鍵を持っている人が誰でも解読できるので意味がない

秘密鍵は、本人だけが知る情報であり、印鑑のようなものです。誰にも知られないように管理します。

公開鍵は、秘密鍵を使って署名されたデータを、誰が書いたのか確認するためのものです。このとき別の人の署名を偽造できないように、認証局という本人を証明する仕組みなどがあります。また、公開鍵をつかって暗号化したデータは、秘密鍵を使わないと読むことができません。

鍵の長さは、秘密鍵/公開鍵が1024ビット、共通鍵は128ビット程度のものまでが米国から輸出できる値? 最近は共通鍵で256ビットのAESなどという形式も見かけます。

S/MIMEなどの署名の場合、本文のハッシュを取り、それを秘密鍵で暗号化(署名)します。公開鍵で暗号化した部分を復号して本文のハッシュと一致すれば、他の人によって改竄されていないということになります。

暗号化の場合、共通鍵を作り、それを公開鍵で暗号化します。本文は、共通鍵で暗号化されます。たぶん。S/MIMEやSSLなどのデータの暗号化もだいたい同じ仕組みです。

この公開鍵/秘密鍵を使えるのは、RSAとDSAという2種類の暗号化方式だけ? DHとか楕円なんとか・・・いろいろあるらしい。

秘密鍵を使って暗号化しても、公開鍵を知っている人の誰にでも読めてしまうので、秘密鍵は署名のみで使い、暗号化が必要なときには相手の公開鍵を使います。

共通鍵(Secret Key)

共通鍵は、相手と同じ鍵を持って暗号/復号をするもので、鍵はどちらも秘密にしておかなければいけません。SSLでは、この共通鍵を毎回新しく作っています。共通鍵を安全に相手に渡すときに、秘密鍵/公開鍵を使っています。データの通信まで秘密鍵/公開鍵を使っているわけではありません。

共通鍵のアルゴリズムには、DES、トリプルDES、AESなどなどがあります。

注意: 英語と日本語で語と意味の対応がちょっと違います。あわせる場合は私有鍵(Private Key)、秘密鍵(Secret Key)としますが、どっちがいいですか?

証明書(Certificate)と認証局(CA) 誰が誰を

秘密鍵と公開鍵を使うことで、相手がつくったデータが途中で改変や盗聴されにくくなるということはわかりましたが、相手が本当に通信しようといている相手であるかどうかという問題が起きてきます。

秘密鍵も公開鍵も誰でもつくれるものなので、相手と会って手渡しで渡してもらったり、一般に知られているのでないかぎり、無闇に信頼することはできません。そこで、公開鍵は信頼できる機関(認証局)が証明する公開鍵証明書という形で利用します。証明書は、認証局が秘密鍵の所有者の情報を確認し、それと公開鍵をセットにして認証局の秘密鍵で署名したものです。どのような内容で信頼できるかという情報もあわせて書かれています。

証明書で重要なのは、公開鍵が正しいかどうかよりは、所有者情報の信頼性の方です。暗号化だけが必要なのであれば、公開鍵のみ必要なので、署名の内容は適当で、認証局の署名が無くてもかまいません。

認証局の署名は、ブラウザなどに最初から入っている認証局の証明書を使って確認できます。信頼するデフォルト以外の認証局があれば追加することもできますし、信頼したくない認証局があれば、外すこともできますね。

一部の認証局では、(公的証明書などの)本人確認を行わずに証明書を発行するところもあります。これではサーバがSSL証明書の申請者によって運営されているという証明にはなりますが、申請者が誰であるかはわかりません。このような認証局は信頼できないものとしてリストから外しておく必要もあるかもしれません。

秘密鍵と公開鍵は、その元になる乱数とセットで秘密鍵ファイルに保存されています。

証明書は、公的な本人確認のための証明書(運転免許証など)と対応する電子的な存在。対応する秘密鍵を持っている人物の所在を証明するものです。

証明書の中でDNというものは、DNSのように固有の名前を表すために使われます。これは証明書だけにあります。

ポリシーというもの

ベリサインなどのルート証明書をみたことがある人には、証明書が何種類かあるのに気付いた人もいるかもしれません。ブラウザではどれも同じように扱われているように思えますが、発行する基準が違ったりするようです。その基準の違いなどなどをポリシーと言ったりするようです。たとえば、対面で本人を確認するとか、郵送だけとか。電子メールアドレスでのやりとりだけとか。それぞれの違いを知った上で相手と通信するかどうか、相手を信頼するかどうかは、本当はルート証明書のポリシーを信頼するかしないかを個別に判断して決めなければなりません。

VeriSignは40bitや56bitのブラウザでも128bitの共通鍵が使えるという証明書(グローバル・サーバID)を発行しています。が、今どき40bitや56bitの暗号しか使えないブラウザはセキュリティホールだらけなのでこういった部分だけで128bitの暗号化ができても何の意味もありません。安い方の証明書で十分です。なぜこのような種類の証明書があるのかというと、昔アメリカからの暗号ソフトの輸出が制限されていた時代に銀行などだけは特殊な証明書を使い128bitの暗号を使えるように制限が緩和され、ブラウザもそれに対応していました。それ用に発行している証明書が今もまだ発行され続けているだけです。無駄なので本当にお勧めしません。128bit以下の暗号化しか使えないブラウザを使い続けている利用者にはSSLを利用させず、まずOSやブラウザを新しくしてからサイトを利用してもらいましょう。サーバ側でもSSL 2.0や56bit以下の暗号は安全ではないので全て使えないようにして128bit以上のSSL 3.0またはTLS 1.xの暗号化だけを使えるようにしておきましょう。

ファイルと鍵

なんだかいろいろあります。署名要求もSSLとS/MIMEでは異なったりします。

 

秘密鍵

公開鍵

所有者情報 認証局の証明
秘密鍵ファイル    
公開鍵署名要求( PKCS#10 CSR)    

公開鍵証明書(X.509?)

  所有者の存在、信頼できる種類、有効期限、認証局の署名?
PKCS#12 認証局の証明書も含めることができる。ブラウザ等へのインポート用
PKCS#7?        
PKCS#8      

署名要求は、PKCS#10だけではなくRFC 4211 CRMFなどいろいろあるようです。

変換のいろいろ

OpenSSLの場合、keytoolの場合

[OpenSSL]

信頼できる種類

各ファイルは、どこで作ってどこへ渡るかということを意識すれば、その役割が見えてくるかもしれません。

秘密鍵は、通常クライアント(利用者)側で作られ、認証局に渡されることがありません。これは秘密鍵ファイル内に保存されます。

秘密鍵と共に作られた公開鍵は、公開鍵署名要求ファイルという形で認証局に渡され、信頼できる情報と関連づけられ公開鍵証明書が作られます。関連づけられることで、公開鍵を認証局を信頼する相手に渡すときに、認証局が証明したものなので信頼しましょうということになります。公開鍵証明書が免許証や健康保険証、会員証などのような役割をするようになります。

秘密鍵や、秘密鍵の含まれているファイルは、人に教えたり渡したりしてはいけません。公開鍵や証明書は、教えてもかまいません。

証明書は、公開鍵の証明になります。証明書の中には公開鍵と所有者の名称などが認証局の秘密鍵で署名されています。公的な証明機関が発行するものは、シリアル番号が振られているので同じ証明書が複数発行されることはありません。同じ秘密鍵に対して複数の公開鍵証明書が存在できます。

Webサーバなどは両方のファイルを持っていて、通信を開始するときに公開鍵証明書をブラウザに送ってきます。

メールの場合は、LDAPというディレクトリサーバに公開鍵証明書を登録しておくことで、はじめての相手にも暗号化したデータを送信できます。

認証局(CA)

認証局は、自己の秘密鍵を使って他の公開鍵に署名し、公開鍵証明書を発行します。有名な認証局の証明書は、ブラウザに最初から含まれていたりすることが多いです。

認証局の証明書には、証明する内容によっていくつか種類がある場合があります。

公開鍵証明書

証明書の署名が認証局のものかどうかは、ブラウザ内の認証局の証明書を確認して行います。

組織内などで利用する場合や、直接公開鍵を交換できるような相手とは、認証局を通さずに直接相手の証明書を信頼してもかまいません。

OpenSSLで作れます。

X.509という形式が使われます。いくつかのバージョンがあり、X.509 v1とX.509 v3がよく使われています。

RFC 2459の4.1にX.509の書式っぽいものをBNFのようなASN.1 [X.208]で書いたものがあります。

参考

証明と暗号化

メールなどの場合、相手の公開鍵を使ってエンコードすることで暗号化することができますが、HTTPでは、証明と暗号化は別のものです。たぶん。

相手が誰かわからなくても暗号化することはできます。また、証明書を使って相手の証明をするだけで、暗号化をしないこともできますね。

秘密鍵/公開鍵の鍵の長さが512ビットや1024ビットでも、通信するときの共通鍵は40ビットや128ビットです。最近は256ビットのものもあるようです。

鍵とファイル

いろんなファイルの種類があります。

とりあえず混乱してみましょう。

秘密鍵と証明書のセット

公開鍵/証明書

秘密鍵

暗号化の仕組み

秘密鍵/公開鍵編

暗号化するためには、秘密鍵と公開鍵のペアを使います。RSA社がみつけた2つの大きな素数を掛け合わせると、もとの素数を調べるのに時間がかかるというような仕組みを使って暗号化します。もとの素数はどちらも知らなくていいのですが、別の数と素数の掛け合わせの組み合わせを使って、暗号化したり複合化したりします。詳しいことはどこかを見てください。

素数 p と q

ある数 a と b

p と q をもとにして、a を法則内で適当に決めます。p、q からa と対になる b を決め、秘密にします。

pとqは秘密にします。pqとaを公開鍵として公開します。pqとbを秘密鍵として保管します。pとqは秘密鍵の中にもあるのかもしれませんが、無くしてしまってもいいようです。

ほかにDSAというのもあります。

共通鍵編

公開鍵暗号は時間がかかるので、通信には向きません。公開鍵方式で共通鍵だけを交換してあとは共通鍵を使うのがSSLなどの仕組みです。(あとで)

DES、AES、RC2,RC4,RC5などがあったかもしれません。

DES

まずは古くからのDESについて調べてみましょうか。詳しい資料がない・・・。 FIPS PUB 46というところで正式な規格になっています。

64ビット毎に暗号機にかけて暗号化していきます。

トリプルDES

では、DESで暗号化、復号化、暗号化と3回変換処理をしています。

参考

AES

証明/署名の仕組み

証明のしくみは、データが改変されていないという証明と、データを作って送信した組織が存在するかという証明との2つが必要です。

データが改変されていないということだけであれば、適当な人物が送信者のふりをしてデータを作成しても、その人の顔をみることができるわけではないのでわかりません。これでは肩書や社名などを実在するものにしてしまえば、簡単にだませてしまえます。

たとえば、A社が存在するとします。B社がA社のふりをして、www.A.com というドメインでサービスをはじめます。客(利用者)はA社だと思ってwww.A.comを利用しますが、B社のサービスを利用してしまうことになります。

署名/証明書を正しく利用すれば、このようなことも防ぐことができます。

A社の名前の入った証明書を、A社はC認証局で発行してもらいます。発行してもらうためにはA社を証明する書類などをC認証局に送ります。この証明書をサーバに入れて使うことで、ブラウザから鍵のマークのところを見てA社であることが確認できます。

相手がどのような組織かは、TCPで接続してすぐに証明書を確認します。クライアント側の証明書をサーバに渡すこともできますが、それは少ないようです。TCPの接続が切れない限り、相手を信用することができます。

シングルサインオン

シングルサインオンとかシングルサインインとかいうものがあります。一般にはあまり普及しているわけではありませんが、普及するといいものです。

手元で秘密鍵と公開鍵のペアを作ります。秘密鍵は、手元に置き、パスワード等で保護されます。公開鍵の証明書をログインしたいサーバに登録します。公開鍵は複数のサーバに登録できるので、1つの秘密鍵で複数のサーバにアクセスできます。

シングルサインオンの鍵ペアを作る場合、1つのアプリケーションで1つの鍵ペアを作って、他のアプリケーションとは共有しないのが普通のようです。SSLのほか、SSHなどで使えます。

しくみ

クライアント証明書がサーバの知っているCAから連鎖されているかどうかと、内容とを見ます。

クライアントとサーバ

SSLが使えるものには、http以外にもいろいろありますが、ここではサーバ側にApacheなどとOpenSSL、クライアントにMozillaということで説明をしてみましょうかね。

クライアント編

MozillaやNetscapeなどなどのブラウザには、鍵のマークがついています。時々これが閉じている黄色い(青もある?)マークに変わることがあります。また、赤い壊れたマークになることもあります。

鍵のマークをクリックしてみましょう。本当は、これが通信する相手であることを確認しないと違う相手と通信していたということもあり得るのですが、Webに書かれた情報のみで相手を信頼してしまっていることが多いようですね。

鍵の管理

(予定)

サーバ編

とりあえずOpenSSLを使ってみるところから。

インストールは、Apacheのところでメモしてます。Vine Linuxの場合は、/usr/share/ssl/ なんてところに設定ファイルなどがあるようです。

OpenSSLにはサブコマンドがいろいろあります。それぞれに役割があります。

其の一 証明書をつくる

証明書は、自己署名証明書というものがつくれます。また、(他の)認証局に証明書を発行してもらうためのCSR(公開鍵証明書申請)というものを作るのが一般的です。

秘密鍵のみつくる [サーバ設置者|個人鍵作成者|認証局用鍵作成者]

秘密鍵をつくる

openssl genrsa -out ファイル名.pem キーの長さ { 512 | 1024} -rand 乱数ファイル { -des3 | -des | -idea }

乱数ファイルは、秘密鍵が特定の値に偏らないようにするためのファイルらしいです。なんでもいいので指定しておけばいいでしょう。

証明書署名要求(CSR PKCS#10形式)をつくる [サーバ設置者|個人鍵作成者|認証局用鍵作成者]

CSRを扱うのはreq です。秘密鍵がある場合は -key で指定します。無い場合は -newkeyと-keyoutで秘密鍵も作ります。

ここで、証明書に埋め込むための所在地、組織名、サーバ名や個人名、メールアドレスなどを入力します。

国、州や都道府県、市区町村、組織、部署、名称、メールアドレスなどの順で入力します。サーバの場合は名称の部分にサーバ名を入れ、メールアドレス以下はなくてもかまいません。個人や組織の場合は名称に個人名などを入れましょう。

認証局(CA)用などで自己署名証明書をつくる場合には、-x509オプションを使います。

openssl req

x509証明書の中身を確認する場合

openssl x509 -in 証明書ファイル名 -text

ここで作られたCSRファイルと自己を証明できる書類などを認証局に提出します。

証明書に署名する [認証局]

申請者から証明書署名要求(CSR)ファイルを受け取ったら、書類とCSRの中身を比較しながら署名します。

設定は、いろいろありますが・・・認証局の各種設定ができていれば、

openssl ca -in 申請書CSRファイル.p10 -out 申請者の証明書 -keyfile 認証局の秘密鍵 -cert 認証局の証明書 -config 設定ファイル

のような感じで証明書を発行できます。-days などのオプションもconfigで指定した値以外のものを設定したい場合に利用できます。

認証局の秘密鍵公開鍵もconfigファイルに書かれていれば省略できるかもしれません。利用目的もファイル内で指定できます。

認証局の証明書をブラウザやメールソフトに入れておくことで、認証局が署名した証明書も利用者が信頼できるようになります。1つの証明書だけを発行/利用するのなら、認証局があってもなくても利用の手間は変わりません。そのサーバの証明書自体をブラウザに入れておけばいいのです。
認証局は、勝手に信頼できない証明書に署名されないように対策をしていなければ、信頼してはいけません。

設定ファイル

設定ファイルがありますね。この中身はいくつかに分かれているようです。証明書署名要求(CSR)や自己署名証明書を作る場合には、[req] の部分からたどっていきましょう。VineLinuxの場合は、x509形式のときはCAの証明書を作り、その他の場合は普通のCSRを生成するようになっているようです。

[req]

x509_extentions = v3_ca # x509オプションの場合は認証局(CA)の自己署名証明書を生成する?

[v3_ca] # CAの証明書の設定項目

keyUsage 鍵の使用方法

証明書発行のプロトコル

FAQ?

わからないことをならべてみる。

Q.ひとつの秘密鍵に対して複数のCAから発行された複数の証明書を作った場合はどうなりますか? それぞれが別の署名?

A.複数の証明書を使う必要はないのかもしれませんが、証明書を使い分けることができるでしょう。基本的に同時に使うことができるのは1つだけです。

Q.サイトシールというのを時々見かけるが、あれは安全か?

A.SSLなどと比べると、あまり安全とはいえません。

  証明 詐称防止 暗号化(盗聴防止)
サイトシール ×
SSL

ドメインと所有者の関係の証明にはなります。ブラウザがRefererを使っていることと、

Q.証明書の期限切れで更新のときには秘密鍵/公開鍵、サーバの署名、シリアル番号はそのままで、証明書に書かれた有効期限と認証局(CA)の署名だけが新しくなる?

A.調査中。どっちにでもできるかもしれません。鍵も新しく作っておいた方がいいですね。

参考

書籍

細かな仕様

で、どこから解剖してみようかと思ったのですが、鍵などのファイルを外から1枚ずつはがしてみることにしましょう。いちばん外側で、よく見るのはBASE64でエンコードされた署名要求(PKCS#10?)などでしょうか。これらのファイルは、まずバイナリ形式にしてしまいます。

そうすると、ASN.1 (ASNはAbstract Syntax Notationの略)のDER というエンコードされた状態のファイルができあがります。ほとんどのX.509 とかPKIでのデータ形式は、このASN.1とかDERな形か、それをBASE64でテキスト型にした形式をしています。ASN.1は、構造体のようなものかな。BASE64はとりあえずわかると思うので、ASN.1構造 でのPKCS各形式を調べておくのがいいでしょうか。

ASN.1 という書式は、ISO 8824になっているようです。RFC では、どれかな。

データの種類は、オブジェクトIDで識別することができるようになっているはず・・・です。

参考


[しいしせねっと]