2016年2月21日日曜日

Webサービスにおける暗号化の基本 / SSL,https

mainpic

これまでの話で通信に関する暗号化の基礎的な要素の理解を進めてきました。

共通鍵と公開鍵という仕組み存在し、デジタル署名を行うことが可能でした。さらに、公開鍵の所有者を第三者が認める電子証明書があり、第三者機関を認証局と呼んでいましたね。

一番の脅威である「なりすまし」を認証局の仕組みを利用して防ぎ、デジタル署名を利用し「改ざん」が検知出来るようになり、鍵の仕組みをきちんと運用することにより「盗聴」されないように暗号化され、電子証明書から「否認」を防止できました。

さて、最後となる今回はこれらの技術を掛けあわせて動いているSSL: Secure Sockets Layerの仕組みをまとめていきます。


Webサービス開発における暗号化の基本

第四回目の今回は、

  1. 共通鍵暗号化方式
  2. 公開鍵暗号化方式
  3. デジタル署名(電子署名)
  4. 電子証明書
  5. 認証局
  6. オレオレ証明書
  7. SSLの仕組み(今日はここまで)

最後はSSL(https)の仕組みに関してです。


SSL: Secure Sockets Layer

SSLの仕組みの説明の前に、用語の整理を行います。

  • SSL
    TCP/IPネットワークで、データを暗号化して送受信するプロトコル。OSI参照モデルではセッション層に位置している。

  • https
    SSLによって提供されるセキュアな接続の上でアプリケーション層のhttp通信を行うこと。

  • TLS: Transport Layer Security
    SSLはNetscape Communicationsが開発したが、後にSSL3.0を元にTLS1.0としてRFCに定められた。特に区別する場合を除きSSLと同等のものである。

実はhttpsというプロトコルは存在せず、HTTP over SSL/TLSという二つのプロトコルを組み合わせたものをhttpsと呼んでいます。

SSLの仕組み

要約すると、クライアントがサーバーの電子証明書から公開鍵を取り出して共通鍵を暗号化しサーバーに返送、サーバーは秘密鍵を使って復号化し、その後は共通鍵暗号化方式で通信を行うというもの。

少し細かく見ていきましょう。

Created with Raphaël 2.1.2WebサーバーWebサーバークライアントクライアント認証局から電子証明書を発行してもらう。サーバー内に秘密鍵とセットで保持。サーバー秘密鍵電子証明書SSL接続要求電子証明書を送信認証局の電子証明書を確認(ルート証明書などを利用)認証局の公開鍵で復号化し電子証明書から公開鍵を取得サーバー公開鍵共通鍵を生成 *サーバー公開鍵を使って暗号化サーバー公開鍵暗号化された共通鍵共通鍵を送信秘密鍵を使って復号化サーバー秘密鍵電子証明書共通鍵共通鍵を使って通信共通鍵を使って通信

クライアントが共通鍵を生成する箇所がありますが、正確には共通鍵の基となるプリマスターシークレットというものを生成します。サーバーは受け取ったプリマスターシークレットを元にマスターシークレットを生成し、共通鍵を得ます。

仕組みは以上です。

実際にどのように組み込んでいるのか、シンプルなオレオレhttpsサーバーを構築してみました。

オレオレは「自己署名証明書」を利用することを意味していますw


nodejsによるSSL通信

まずはWebサービスにおける暗号化の基本 / 認証局でも作ったように、鍵、署名リクエスト、自己署名証明書を作成します。

openssl genrsa 2048 > my.key # 鍵
openssl req -new -key my.key > my.csr # 署名リクエスト
openssl x509 -days 3650 -req -signkey my.key < my.csr > my.crt # 自己署名証明書

これを使って、nodejsでサーバーを作るのは以下のようなソースになります。

var https = require('https');
var fs = require('fs');
var options = {
  key: fs.readFileSync('./my.key'),
  cert: fs.readFileSync('./my.crt')
};
https.createServer(options, function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end('Hello World\n');
 }).listen(1338, '127.0.0.1');
 console.log('Server running at https://127.0.0.1:1338/');

my.keyとmy.crtを利用していますね。上記フロー図のWebサーバーのどこで利用されるのかが検討がつくかと思います。

これをsslserver.jsと名づけて保存し、

node sslserver.js

とすれば、https://127.0.0.1:1338でhttps通信することが出来ます。

ただし、自己署名証明書を利用しており、正しいCAを通過していないので以下のように赤くなり、信頼できませんといわれます。
https

以上がsslの仕組みとサンプルサーバーになります。

では、良いインプットと良いプログラミングを。

0 件のコメント:

コメントを投稿