Wireless・のおと

SSLのはなし

ブログ
技術解説 セキュリティ 昔話 HTTP SSL X.509

前回はインターネットの代名詞 HTTP プロトコルについて解説しましたが、HTTP の暗号化に多用されている SSL(およびその発展型である TLS)と HTTP は「事実上不可分」と書きました。今回はその SSL/TLS についての解説です。

前回も述べたように、SSL 3.0 と TLS 1.0 の基本動作はほぼ同じです。この記事では SSL3.0 を基本として、TLS については必要に応じて註釈を入れることにします。使用する用語も SSL/TLS 共通の内容については「SSL」を基本とし、TLS 以降に特有の記述のみ「TLS」と記します。

SSL の基本動作


SSL の動作は「初期情報交換(Hello)」「暗号鍵の交換(Key Exchange)」「暗号通信の開始(Change Cipher Spec)」の3段階からなります。簡単に書くと

クライアント   サーバ
→ Client Hello →
← Server Hello ←
→ Client Key Exchange →
→ Change Cipher Spec →
← Change Cipher Spec ←
(以降の通信は暗号化)

という風になります。これだけ見ると単純ですね。

SSL の通信データ構造は「レコード」という外枠にまとめられ、必要に応じてレコードの中に「メッセージ」が含まれます。C 言語風に書くと
 

struct Message {
  unsigned char msg_type;
  unsigned char length[3];
  unsigned char body[*];
};

struct Record {
  unsigned char type;
  unsigned char version[2];
  unsigned char length[2];
  union {
    struct Message message[*];
    unsinged char plain_data[*];
  } record_data;
};


のような構造になります。セッション確立後の暗号通信でもレコード構造は維持され、暗号化されたデータが application_dataレコード(type=23)の plain_data 部分に収められて送受信される格好になります。

メッセージ長が 24bit なのに外側のレコード長が 16bit というのは奇妙な感じがしますが、SSL では同じ type を持つレコードに含まれるデータは連続したものとして扱い、レコードは分断(Fragmentation)して送信しても構わないことになっています。SSL メッセージの多くは数百バイト以内ですが、検証用の親証明書(CA 証明書)をまとめて一緒に送る証明書チェーン(Certificate Chain)を使用する場合は 100K バイト以上に達することもあり、そのような場合にはメッセージが複数のレコードに分割されることになります。

SSLメッセージの分割

分割再結合を前提としていても、その為に必要となるオフセットやシーケンスのような情報は SSL のデータ構造には無く、そういった機能は下位層に委ねられています。これは TCP のようにデータ順序を保証するプロトコル上で動作するぶんには問題ないのですが、そうでないプロトコル上で動作させようとすると厄介で、WiFi エンタープライズ認証で使われる EAP-TLS 系の実装が複雑になる原因の一つになっています。

SSL のメッセージ長は通常レコードにぴったり収まりますが、TLS では時としてレコードがメッセージ全長より大きい場合があります。これは RFC3546(2003) で定義された TLS メッセージ拡張という仕組みで、メッセージ本体の直後に 16bit の拡張情報長(※註)、その後に任意個の拡張情報が TLV 形式(タグ 16bit + 長さ 16bit + 任意長のデータ)で連なる形態を取ります。

TLSメッセージ拡張形式

TLS ではこの機構を用いて SSL には無かった機能(再接続を高速化する Session Ticket だとか ECDH 楕円曲線鍵交換手順の情報だとか)を後付け拡張していますが、実装系やバージョンが異なると拡張情報の取り扱いが異なったりして、互換性問題の元凶になることもあります。

※註:しかし RFC3546/4366 を素直に読む限り、Extended Hello メッセージは compresion method の直後に Extension の TLV 配列が並ぶように見えて、Extension Length なんて何処にも書いて無いんですけどねぇ...何処に定義されているんだろう?

SSL の通信手順

Client Hello 手順

SSL の通信は TCP の接続完了後(SYN-SYNACK-ACK 交換)、クライアント(通常は SYN を送ったノード)からの Client Hello メッセージ(msg_type=1)の送信によって始まります。Client Hello で重要なのはバージョン番号と、クライアントがサポートしている暗号アルゴリズムの一覧(Cipher Suite)です。SSL3.0/TLS ではバージョン番号は全てのレコードの頭に付いていますが、Client Hello ではメッセージの中に改めてバージョン番号を持っています。おそらくレコードにバージョンを持っていなかった SSL2.0 から引き継いだ盲腸のようなものでしょう。
Cipher Suite は 16bit の整数値で、例えば 0x0005=SSL_RSA_WITH_RC4_128_SHA のように、公開鍵暗号+共通鍵暗号+ハッシュのアルゴリズムの組み合わせに関連付けて事前定義されています。SSL3.0 で定義されていた 0x0000~0x001B までの Cipher Suite 値はそっくりそのまま TLS1.0 でも継承されていますが、SSL3.0 で Fortezza 社の IC カード認証用として定義されていた 0x001C~0x001E のうち 0x001E は TLS1.0 の Kerberos 拡張認証(RFC2712)で重複定義されており、この辺りにも IETF の「特定企業の特許製品に対する嫌悪」が垣間見える気がします。
SSL は暗号化だけでなく圧縮プロトコルとしても使えることが考慮されており、Client Hello には Compression Method というフィールドもあります。これは長らく「将来の予約」的な扱いで常に 0(null) 一つだけが入っていたのですが、RFC3749(2004)で 1(DEFLATE) 圧縮アルゴリズムが定義されました。しかし TLS のデータ圧縮オプションはセキュリティに関する考慮が甘かったのか、後になって CRIME や BREACH と呼ばれるセキュリティホール騒動を起こすことになります。

余談:Monkey Cipher

SSL の Chiper Suite には 0x0003(SSL3_RSA_EXPORT_RC4_40_MD5) や 0x0008(SSL3_RSA_EXPORT_DES_40_CBC_SHA)といった「輸出用暗号スイート」が定義されています。これらは RC4 や DES をアルゴリズム本来よりも短い 40bit 鍵として運用し、それを交換する RSA や DH の公開鍵長も 512bit に制限することで「解読しやくすくした」代物です。わざわざ暗号を解読しやすくするなんて「わけがわからないよ」ですが、これはかつて暗号が軍事技術として規制対象になっていた時代の名残です(※註)。民生用として出荷された製品が敵性国の手に渡り軍事技術として流用され、結果としてアメリカの脅威となり国益を損なうことがあってはならない...というわけで、90 年代はアメリカ国家安全保障局(NSA)が現実的時間内に解読可能としていた 512bit 公開鍵・40bit 秘密鍵までが輸出可能、それ以上の強度を持つ暗号製品は「米国内での使用に限る」とされていました。
もちろんこれはユーザーから不評であったばかりか、業界からも「アメリカの国際的製品競争力を弱まらせかえって国益を損なう」と反発を招き、アメリカ議会において激論を招くことになります。2000 年までには段階的に輸出規制が緩和され、あまりに貧弱な 512bit や 40bit の「モンキー・サイファー」は過去のものとなりました。

※註:ただし現在でも暗号に関する輸入輸出規制が完全撤廃された訳ではなく、今でも製品に使用されている暗号技術の一覧申告が必要な国は多いですし、最新最強の暗号技術は軍事機密とみなされることもあります。また「敵性国家」ならぬ犯罪者による暗号ネットワークの悪用は慢性的な社会問題となっていますし、米国で起きた乱射事件の応酬証拠品である iPhone について司法がデータ解読権を握って良いものかどうかという論議など、暗号技術における個人と社会の利害バランスの問題はずっと続いています。

Server Hello 手順

Server Hello は Client Hello に対する返信です。多くの場合、Server Hello 手順は Server Hello, Certificate, Server Hello Done の3つのメッセージから構成されます。Server Hello 手順のメッセージ群が 1 つのレコードにまとめて送信されるか、それぞれ別個のレコードとして送信されるかは実装系によって異なります。
Server Hello メッセージ(msg_type=2) に含まれる情報はおおむね Client Hello と同じですが、大きな違いは Cipher Suite フィールドが「アルゴリズムの一覧」ではなく、サーバが選択したアルゴリズム1つだけを含むことです。
Certificate メッセージ(msg_type=11) は X.509 デジタル証明書の送付に使うもので、証明書は SSL におけるセキュリティの肝となる部分です。これについては後で詳しく述べます。
Server Hello Done メッセージ(msg_type=14) は Server Hello 手順の終了を示します。

相互認証の場合

「多くの場合」3つのメッセージから構成されると書いたのは、クライアントからも証明書を送って相互認証(Mutual Authentication)を行う場合、Server Hello 手順には Server Key Exchange メッセージ(msg_type=13)と Certificate Request メッセージ(msg_type=13) が追加で含まれるからです。この場合、クライアントは Client Key Exchange 手順の前に Certificate メッセージ(msg_type=11) と Certificate Verify メッセージ(msg_type=15) を返送します。
相互認証はクライアント(WEB ブラウザ)にも証明書をインストールしなければならない煩雑さが嫌われて WWW 上では殆ど使われず、通常はサーバのみ証明書を用いて認証、暗号通信開始後に HTTP POST でユーザ名・パスワードを暗号化回線上で送る実装が一般的ですが、幸か不幸か WiFi エンタープライズ認証の EAP-TLS では相互認証を用いています。EAP-PEAP や EAP-TTLS では原理的に WEB 認証と同じ「片道認証・暗号化確立・パスワード送信」という実装になっていますが、不幸にして互換性のない似て非なる規格が複数並立する結果になっているというのは以前このブログにも書きました。

Anonymous DH の場合

SSL/TLS の仕様上は、証明書を使わずに公開鍵交換を行う Anonymous Diffie-Hellman(ADH あるいは DH_anon) 手順も定義されています。しかしこれは「定義されている」というだけで現実には殆ど誰も使っていません(※註)。暗号化のみを目的として認証を必要としない場合も「証明書を使わない」のではなく、改竄検証ができない自己署名証明書(Self-Signed Certificate)を用いることが多いです。詳しくは後述の「X.509 デジタル証明書」項を参照してください。

※註:Cisco 社の EAP-FAST エンタープライズ認証は Phase0 の自動プロビジョニングモードに EAP-TLS/ADH を使用していますが、これは ADH 鍵交換の数少ない採用例だと思います。

Client Key Exchange 手順

Server Hello を受け取ったクライアントは証明書を用いてサーバの正当性を確認したあと、示された Cipher Suite に呼応する共通鍵を乱数によって作成し、それを暗号化して Client Key Exchange メッセージ(msgtype=16) を送信します。
RSA 証明書を用いる場合、証明書に示されている公開鍵がそのまま暗号鍵になります。RSA アルゴリズムには対称性があるので、公開鍵を用いて暗号化されたデータは秘密鍵を用いることでしか解読できません。
Diffie-Hellman(DH) を用いる場合は手順が少し異なり、交換された DH パラメータとサーバ・クライアントそれぞれ内部で持つ秘密情報から共通のデータ列を算出します。いずれの場合も回線を盗聴している第三者にはわからない方法でサーバ・クライアント共有の秘密情報が交換され、それが以降のデータ暗号化に使用される暗号鍵となります。

Change Cipher Spec 手順

Client Key Exchange 送信の直後、クライアントは Change Cipher Spec レコード(type=20) を送信し、以降の通信が暗号化されることを通知します。Change Cipher Spec は Handshake レコード(type=22) 中のメッセージではなく、異なるタイプを持つレコードであることに注意してください(※註)。Change Cipher Spec の直後には再び Handshake レコードで Finished メッセージ(msgtype=20) が送信されますが、もはや中身は暗号化されているので普通は読めません。
Change Cipher Spec を受信したサーバも Change Cipher Spec と Finished を返送し、これをもって SSL の暗号回線は確立します。

※註:Change Chiper Spec をメッセージではなくレコード型として定義することによって、同じレコードの中に平文と暗号文が併存することを自動的に禁止しています。こういうのがスマートな仕様設計ですね。一見シンプルにメッセージ型に統一したうえで「Change Cipher Spec message MUST be sent in independent record」とか MUST, MUST NOT を並べて実装上の制約とするのは仕様書屋さんは自己満足でしょうが、実装屋にとっては余計なお世話です。実装屋の全員が仕様書を最初から最後まで一行残さず全文通して読み、提示された全ての条件を完全に理解したうえで実装するわけじゃないのですから...。

SSL の実装

Secure Socket Layer という名前が示すように、SSL/TLS は TCP/IP ソケットとアプリケーション層の間に介入するミドルウェアです。生の(暗号化されていない) TCP ソケット通信では
 

socket_t s;
struct sockaddr_in client_address;
struct sockaddr_in server_address;
char buff[1024];
int len;

(client_address, srever_address の初期化は省略)
s = socket(AF_INET, SOCK_STREAM, 0);
bind(s, &client_address, sizeof(client_address));
connect(s, &server_address, sizeof(server_address));
send(s, "GET / HTTP/1.0\r\n\r\n", 18, 0);
len = recv(s, buff, sizeof(buff), 0);
close(s);


のようにして接続しますが、これを SSL 対応にすると
 

socket_t s;
struct sockaddr_in client_address;
struct sockaddr_in server_address;
char buff[1024];
int len;
SS_CTX* ctx;
SSL* ssl;

(client_address, srever_address の初期化は省略)
s = socket(AF_INET, SOCK_STREAM, 0);
bind(s, &client_address, sizeof(client_address));
connect(s, &server_address, sizeof(server_address));
SSL_ctx = SSL_CTX_new(SSLv3_client_method());
ssl = SSL_new(ctx);
SSL_set_fd(ssl, s);
SSL_connect(ssl);
SSL_write(ssl, "GET / HTTP/1.0\r\n\r\n", 18);
len = SSL_read(ssl, buff, sizeof(buff));
close(s);
SSL_free(ssl);
SSL_CTX_free(ctx);


のようになります。socket_t の「外側」に SSL 構造体ポインタが作られ、connect, send, recv などのソケット API の「上に被さる」格好で SSL_connect, SSL_write, SSL_read などの SSL API が実装されることになります。すなわち、とあるソフトウェアを SSL を用いて暗号化したい場合、原則としてソースコードを書き換えて再コンパイルする作業が必要になり(※註)、これが SSL の制限の一つです。これに対して IPsec では下位のプロトコル階層で暗号化が行われるので、アプリケーションは無改造のまま暗号化に対応できます。
SSL の API に標準規格はありませんが、オープンソースライブラリの OpenSSL が広く普及しているため、独自実装の場合でも OpenSSL に似せた API とする場合が多いようです。

※註:「原則として」と書いたのは、外部プログラムを介する「SSL トンネル」や外部ハードウェアを介する「SSL VPN ルータ」のように、ソースコードを改変せずに SSL 暗号化対応する方法もあるからです。

X.509 デジタル証明書

SSL/TLS で用いられている X.509 デジタル証明書は OSI プロトコル規格の遺産です。OSI には世界中のデータというデータを統一して一括管理する X.500 ディレクトリ管理プロトコル(DAP) という壮大な構想があり、X.509 はもともと X.500 上での認証用に開発されたものでした。

「デジタル証明書」というのは、とあるデータの塊に対してハッシュ(チェックサム)を算出し、そのハッシュを秘密鍵で暗号化した演算結果を添付したものです。これを「署名(Signature)」と呼びます。情報の受信者は同じデータの塊からハッシュを再計算し、署名をデータの中に含まれる公開鍵で復号した結果が一致することをもってデータの正当性を検証できます。しかしこの手順だけでは、ハッシュと公開鍵が丸ごと差し換えられた場合の検証はできません。

x509-self-l.jpg

(図) 自己署名証明書。Issure と Subject が同じ DN を持っている。公開鍵と署名が一致することは確認可能だが、両者まとめて差し換えられた場合は検証できない。

そこで X.509 では「親証明書(CA 証明書)」というものが出てきます。この場合、証明書に添付される署名は証明書に含まれる公開鍵ペアではなく、証明書を担保する認証局(CA)によって作成されます。認証局は非公開の秘密鍵を用いて署名を行い、秘密鍵とペアになる公開鍵を CA 証明書として外部に公開します。

受信者は CA 証明書の公開鍵を用いて署名を復号し、証明書のハッシュ値と一致することを確認することで検証を行います。攻撃者がハッシュと公開鍵を差し換えようとしても、認証局の秘密鍵を入手することなく CA 証明書と一致するハッシュ値は(天文学的な試行時間をかけないかぎり)作成できません。

x509-ca-l.jpg

(図) 外部署名証明書。Issure は「親証明書」の Subject を指す。署名は親証明書の秘密鍵をもって行われるため、証明書の内容を差し換えてなおかつ署名を一致させるのは非常に困難。

CA 証明書は更に別の CA 証明書で署名されている場合があり、遡ってゆくと「無条件で信用することが前提」のルート証明書に行き付きます。ルート証明書は Verisign, GlobalSign, GeoTrust など社会的信用の高いセキュリティ企業から発行され、Windows などのパソコン OS には十数種類の代表的なルート証明書が事前インストールされています。この証明書ツリーというシステムがあるために、攻撃者が同じ Subject を持つ偽の CA 証明書を作って署名を一致させることも難しくなっています。
全ての証明書には期限があり、また(ごく稀に)セキュリティ問題が発生して期限前に CA 証明書が失効したりするので、Windows では Windows Update によって最新の証明書が更新される仕組みになっています。

X.509 subject と URL の関係

さてこのように X.509 デジタル証明書は「とあるデータの塊」に対して正当性検証のメカニズム(通称「お墨付き」)を与える仕組みですが、WEB サーバの正当性を担保するためには「何」に対して証明書を与えれば良いのでしょうか?物理的存在であるサーバそのものを証明することはできませんし、頻繁に更新される HTML のデータや永続性が保証できない IP アドレスに対して証明書を発行することは現実的ではありません。

X.509 において、証明すべき対象は X.500 DN というフォーマットで示されます。DN というのは Distinguished Name の略で、世界中のデータを統合管理することを目指した X.500 における「そのデータに与えられる唯一無二の識別子」です。DN は国(C)・州/県(ST)・市/町(L)・組織(O)・固有名(CN) など階層構造をなす複数のフィールドにそれぞれ名前を付けて束ねたもので、例えば "C=US,ST=CA,L=Santa Ana,O=STA,CN=YS" のようなものになります。
もともとの OSI 構想では X.509 に書かれた DN はそのまま X.500 の DN 識別子でもあるため、「その証明書が何を検証するものか」のは自明でした。しかし OSI ならぬ TCP/IP プロトコルで接続された WWW ネットワークでは DN は用いられません。WEB サイトを特定する識別子は http://www.silex.jp のような URL ですが、ならば C=jp,O=silex,CN=www みたいに、URL を分解して DN に当て嵌めれば良いのでしょうか?(※註)

※註:RFC2247(1998) では DC フィールドを新しく定義し、DNS 名を DC=www,DC=silex,DC=jp のような DN に展開する方法が定義されています。しかし、この仕様は誰も使っていないと思います。少なくとも WWW 世界では使われていません。

現実の WEB 証明書では CN に URL のドメイン名(例えば "www.silex.jp")を入れており、これを受信したブラウザでは C やら O やらのフィールドは無視して CN とドメイン名の一致だけを検証しています。更にいつの頃からか、CN に含まれる * 文字をワイルドカード一致としてみなす実装も普及してきました。例えば北米 Google WEB サイトの証明書は CN=*.google.com となっており、www.google.com だろうが mail.google.com だろうが同じ証明書で認証できるようになっています。
もともと「データに与えられる唯一無二の識別子」だった X.500 DN の出自からすると、何にでも一致するワイルドカード文字を DN に含めるなんて本末転倒みたいな話ですが、OSI 用に開発された X.509 を TCP/IP や WWW に流用するための「スリ合わせ」のようなものですね。(※註)

※註:しかし、この「WEB サイト用証明書は subject DN の CN フィールドにドメイン名を入れる」「ドメイン名にはワイルドカード文字を混ぜることもできる」という実装がどの仕様書で規定されているのか私は知りません。ワイルドカード文字については RFC2459(1999) に既述が見られますが、これは subject ではなく subjectAltName 拡張フィールドに対する既述であり、subject DN に直接ワイルドカードを入れて良いとは読めません。最新版の RFC5280(2008) でもこれは同じですし、subject DN に関する既述(4.1.2.6 章)にも「認証対象が WEB サーバである場合は subject DN の CN フィールドにドメイン名を入れるべし」とは書いてありません。あるいは RFC ではなく W3C の仕様書の何処かに定義されているのかも知れませんが、昔からちょっと気になっている(でも深く調べようとは思わない)ところです。

証明書の有効期限にまつわる小話

前述したように X.509 証明書には有効期限があり、これは notBefore と notAfter という2つの日時で挟まれた期間として記されます。しかし小型の組み込み機器にはバッテリバックアップつきの時計(リアルタイムクロック)を持たないものも少なくなく、毎回電源投入時 1970 年 1 月 1 日としてスタートしたりするので、「証明書日時を検証しない」ように SSL の設定オプションを弄る(あるいはパッチを当てる)のを忘れると、EAP-TLS で接続しようとすると「証明書が有効期限前」と判断されて繋がらないトラブルがよく起きます。
notBefore / notAfter は UTCTime ないし GeneralizedTime というデータ型を取ります。どちらも日時を数字の羅列として表現した文字列ですが、UTCTime は年表記が2桁なので 2000 年を超えると一周してしまいます。現在の X.509 規格では UTCTime の表現範囲を 1950~2049 年と定義しており、2050 年以降の日時を表記する場合には新たに定義された年表記4桁の GeneralizedTime を使うべしとしています。
「世界中の全データに唯一無二の識別子を与えて統合管理する」という壮大な OSI 構想において、その標準日時データ型が年表記2桁しか考えていなかったというのは「何やってんだよ」感を抱きますが、こういうのも世間にはよくある話ですね。
 

SSL/TLS の応用

HTTP 以外の暗号化

SSL/TLS は HTTP の暗号化・認証プロトコルとして WEB 上で広く使われていますが、ソースコードを少し弄るだけで既存のプログラムを暗号化できるため、HTTP 以外の暗号化にも使われています。代表的なものはメールプロトコルの SMTP と POP3、ファイル転送プロトコルの FTP でしょう。
HTTP over SSL (https) は伝統的にポート番号 443 を使用します。POP3 over SSL は 995、FTP over SSL は 990 が割り当てられていますが、https ほど一般的ではなくソフトやプロバイダによって異なるポートを使うこともあります。SMTP over SSL に至っては IANA にポート番号の登録すらなく、465 や 587 など複数のポート番号が混用されています。

WiFi エンタープライズ認証

SSL/TLS は EAP 上の認証プロトコル EAP-TLS (およびその眷族である TTLS, PEAP, FAST) にも使われていることは何度か述べてきました。もともと TCP のようなストリーム・トランスポート上で動作することを前提に設計された TLS をパケットメッセージ交換プロトコルの EAP に実装しているため、実装はかなりえげつない事になっています。特定の RADIUS サーバで認証が通らない!なんてトラブルが出たとき、通信ログをダンプして EAP ペイロードを抜き出しブチブチに千切れた TLS のネゴシエーションを再生して追いかける作業なんて泣きたくなります。

SSL VPN

SSL/TLS は VPN(Virtual Private Network) にも応用されています。VPN は組織内の非公開ネットワークを公衆回線を暗号化して経由し接続する技術で、かつては PPTP(GRE), L2TP(※註), SOCKS など何種類もあって混迷していましたが、現在では IPsec と SSL の2つが2大派閥を形成しています。

※註:L2TP は下位層に IPsec を利用しますが、IP プロトコルしか通さない IPsec と異なり任意の MAC フレームを扱う「カプセル・フレームワーク」を前提としているため、IPsec VPN とは別扱いになることが多いです。

SSL VPN の特長は WWW 用の通信インフラに「相乗り」できるため、プロキシや NAT ルータを超えるのが容易なことです。公衆 WiFi 回線から VPN を接続するなんて、IPsec ではまず不可能でしょう。また http 用の暗号や認証の仕組みを流用できるため PC にインストールするソフトが小さくて済み、設定も容易という特長もあります。この特長によって SSL VPN は当初モバイル接続用として普及し、拠点間の VPN 接続には専用の IPsec VPN ルータが用いられ住み分けてきたのですが、最近は拠点間接続に用いる SSL VPN ルータも増えてきました。

SSL と IPsec

SSL/TLS は基本動作が「Hello 交換」「証明書交換」「鍵交換」のシンプルな3段階で、オプション選択肢が多くありません。仕様上は双方向認証や Anonymous DH もありますが、特にインターネット上の WEB サーバではほとんどの場合「サーバ証明書の subject CN フィールドからサーバのドメインのみ認証」「暗号回線確立後に Basic Authentication や HTTP Post を使ってユーザー認証」というワンパターンで運用されています。「仕様が比較的単純」で「使われ方がワンパターン」ということは、「できることも限られる」という制約と引き換えに「わかりやすい」「互換性が高い」というメリットとして、結果的に利用者にとっても管理者にとっても実装者にとっても「使いやすい」ものとなっています。

これに対して IPsec/IKE は「何でもできるように」と矢鱈にオプションを増やした結果、設定・運用に困難のつきまとうプロトコルになってしまいました。もちろんデジタル技術ですから「全てが正しく実装され正しく設定されていれば正しく動くはず」ですが、そこまで持ってゆくのは大変で、特に異機種・異 OS が混在する場合は絶望的にすらなります。実装者にとってもアホみたいに多い組み合わせの全てについて動作検証をかけるのは大変な工数ですし、往々にして見落としがあって「AH トンネルヘッダ + ESP + 認証トレイラーでペイロード長が 8 の整数倍-1 の場合にハッシュが合わないことがある」のような発現しにくい潜在バグが残ったりして、ますます互換性が怪しくなるスパイラルを起こしてしまいます。

IPsec が「何でもできるセキュリティプロトコル」を目指したことには理由も事情もあるのですが、結果から見ると「やっぱり Keep It Simple and Stupid だよなぁ...」と思わざるを得ません。賢い人が大勢集まってアイデアを持ち寄った「民主的」な仕様よりも、特定企業の特定実装から生まれた「独裁専制的」な仕様のほうが結果的に広く使われたりするというのも、これまた世間にはよくある話です。

まとめ

以上、SSL/TLS について動作原理から余談の数々に至るまでまとめてみました。改めて書いてみると OSI 構想の遺産やら冷戦時代の記憶やら、いろんな過去を抱え込んでいることを実感します。なんせ SSL2.0 の発表が 1995 年ですから、IEEE802.11 無線 LAN (無印が 97 年、11b が 99 年)よりも古いわけですね。
SSL を開発・発表した Netscape Communications 社は消えてしまいましたが、SSL/TLS は TCP/IP 上のセキュリティプロトコルとしてデファクトスタンダードの座にあり、これに代わるものが出てくる気配も当分なさそうです。「Netscape Communications」の名前もまた、SSL/TLS の抱える過去の一つとして未来に伝えられてゆくのでしょう。

関連リンク

製品のご購入・サービスカスタマイズ・資料請求など
お気軽にお問い合わせください