この用語をシェア
SSL/TLSとは
SSL(Secure Sockets Layer)/TLS(Transport Layer Security)は、インターネット上でデータを暗号化して安全に送受信するためのプロトコルです。HTTPSをはじめとする様々なセキュアな通信において使用されており、現代のWebセキュリティの基盤技術となっています。
SSLとTLSの関係
SSLは初期のプロトコルで、TLSはその後継として開発されました。現在では主にTLSが使用されていますが、慣習的に「SSL」と呼ばれることが多いです。
バージョン履歴
プロトコル | バージョン | リリース年 | 状態 |
---|---|---|---|
SSL | 1.0 | 1994 | 非公開 |
SSL | 2.0 | 1995 | 非推奨 |
SSL | 3.0 | 1996 | 非推奨 |
TLS | 1.0 | 1999 | 非推奨 |
TLS | 1.1 | 2006 | 非推奨 |
TLS | 1.2 | 2008 | 利用可能 |
TLS | 1.3 | 2018 | 推奨 |
SSL/TLSの主要な機能
- 暗号化:データの内容を第三者が読めないように暗号化
- 認証:通信相手が本物であることを確認
- 完全性:データが改ざんされていないことを保証
- 否認防止:送信者が送信を否認できないようにする
SSL/TLSハンドシェイク
クライアントとサーバーが暗号化通信を開始する前に、以下の手順でハンドシェイクを行います。
TLS 1.2 ハンドシェイク
- Client Hello:クライアントが対応する暗号スイートを送信
- Server Hello:サーバーが暗号スイートを選択して送信
- Certificate:サーバーがSSL証明書を送信
- Server Key Exchange:必要に応じて追加の鍵情報を送信
- Server Hello Done:サーバーがハンドシェイクの完了を通知
- Client Key Exchange:クライアントが暗号化された鍵を送信
- Change Cipher Spec:暗号化通信の開始を通知
- Finished:ハンドシェイクの完了を確認
TLS 1.3 ハンドシェイク
TLS 1.3では、ハンドシェイクが簡素化され、1-RTT(Round Trip Time)で完了します。
Client Server
ClientHello
+ KeyShare -------->
ServerHello
{EncryptedExtensions}
{CertificateRequest*}
{Certificate*}
{CertificateVerify*}
{Finished}
<--------
{Certificate*}
{CertificateVerify*}
{Finished} -------->
[Application Data] <-------> [Application Data]
暗号化技術
対称暗号化
暗号化と復号化に同じ鍵を使用する方式です。
アルゴリズム | 鍵長 | 特徴 |
---|---|---|
AES | 128, 192, 256 bit | 現在の標準、高性能 |
ChaCha20 | 256 bit | モバイルで高性能 |
3DES | 168 bit | レガシー、非推奨 |
非対称暗号化(公開鍵暗号)
公開鍵と秘密鍵のペアを使用する方式です。
アルゴリズム | 鍵長 | 特徴 |
---|---|---|
RSA | 2048, 3072, 4096 bit | 広く使用されている |
ECDSA | 256, 384, 521 bit | より短い鍵長で同等の安全性 |
EdDSA | 255, 448 bit | 高性能、新しい標準 |
ハッシュ関数
データの完全性を保証するために使用されます。
アルゴリズム | ハッシュ長 | 状態 |
---|---|---|
SHA-256 | 256 bit | 推奨 |
SHA-384 | 384 bit | 推奨 |
SHA-512 | 512 bit | 推奨 |
SHA-1 | 160 bit | 非推奨 |
MD5 | 128 bit | 非推奨 |
SSL証明書
SSL証明書は、サーバーの身元を証明し、公開鍵を含むデジタル証明書です。
証明書の種類
種類 | 検証レベル | 特徴 |
---|---|---|
DV(Domain Validated) | ドメイン所有権 | 自動発行、低コスト |
OV(Organization Validated) | 組織確認 | 組織名を証明書に記載 |
EV(Extended Validation) | 厳格な組織確認 | ブラウザで組織名表示 |
証明書の構造
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 12345678901234567890
Signature Algorithm: sha256WithRSAEncryption
Issuer: C=US, O=Example CA, CN=Example CA
Validity:
Not Before: Jan 1 00:00:00 2025 GMT
Not After : Jan 1 00:00:00 2026 GMT
Subject: C=JP, ST=Tokyo, L=Tokyo, O=Example Corp, CN=example.com
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public Key: (2048 bit)
X509v3 extensions:
X509v3 Subject Alternative Name:
DNS:example.com, DNS:www.example.com
X509v3 Key Usage:
Digital Signature, Key Encipherment
X509v3 Extended Key Usage:
TLS Web Server Authentication
Signature Algorithm: sha256WithRSAEncryption
証明書の取得と設定
Let's Encryptでの証明書取得
# Certbotのインストール
sudo apt update
sudo apt install certbot python3-certbot-nginx
# 証明書の取得
sudo certbot --nginx -d example.com -d www.example.com
# 自動更新の設定
sudo crontab -e
# 以下を追加
0 12 * * * /usr/bin/certbot renew --quiet
Nginx設定例
server {
listen 80;
server_name example.com www.example.com;
# HTTPからHTTPSへのリダイレクト
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name example.com www.example.com;
# SSL証明書の設定
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
# SSL設定
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers off;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
# セキュリティヘッダー
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
# OCSP Stapling
ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /etc/letsencrypt/live/example.com/chain.pem;
location / {
proxy_pass http://localhost:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Apache設定例
<VirtualHost *:80>
ServerName example.com
ServerAlias www.example.com
Redirect permanent / https://example.com/
</VirtualHost>
<VirtualHost *:443>
ServerName example.com
ServerAlias www.example.com
# SSL証明書の設定
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/example.com/cert.pem
SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem
SSLCertificateChainFile /etc/letsencrypt/live/example.com/chain.pem
# SSL設定
SSLProtocol -all +TLSv1.2 +TLSv1.3
SSLCipherSuite ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384
SSLHonorCipherOrder off
# セキュリティヘッダー
Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"
Header always set X-Frame-Options DENY
Header always set X-Content-Type-Options nosniff
Header always set X-XSS-Protection "1; mode=block"
# OCSP Stapling
SSLUseStapling on
SSLStaplingCache "shmcb:logs/stapling-cache(150000)"
DocumentRoot /var/www/html
</VirtualHost>
SSL/TLSの実装
Node.js(Express)
const express = require('express');
const https = require('https');
const fs = require('fs');
const path = require('path');
const app = express();
// SSL証明書の読み込み
const options = {
key: fs.readFileSync('/etc/letsencrypt/live/example.com/privkey.pem'),
cert: fs.readFileSync('/etc/letsencrypt/live/example.com/cert.pem'),
ca: fs.readFileSync('/etc/letsencrypt/live/example.com/chain.pem')
};
// セキュリティヘッダーの設定
app.use((req, res, next) => {
res.setHeader('Strict-Transport-Security', 'max-age=31536000; includeSubDomains');
res.setHeader('X-Frame-Options', 'DENY');
res.setHeader('X-Content-Type-Options', 'nosniff');
res.setHeader('X-XSS-Protection', '1; mode=block');
next();
});
// HTTPからHTTPSへのリダイレクト
app.use((req, res, next) => {
if (req.header('x-forwarded-proto') !== 'https') {
res.redirect(`https://${req.header('host')}${req.url}`);
} else {
next();
}
});
app.get('/', (req, res) => {
res.send('Hello HTTPS!');
});
// HTTPSサーバーの起動
https.createServer(options, app).listen(443, () => {
console.log('HTTPS server running on port 443');
});
// HTTPサーバー(リダイレクト用)
const http = require('http');
http.createServer((req, res) => {
res.writeHead(301, { Location: `https://${req.headers.host}${req.url}` });
res.end();
}).listen(80, () => {
console.log('HTTP server running on port 80 (redirect only)');
});
Python(Flask)
from flask import Flask, redirect, request, url_for
import ssl
app = Flask(__name__)
# セキュリティヘッダーの設定
@app.after_request
def set_security_headers(response):
response.headers['Strict-Transport-Security'] = 'max-age=31536000; includeSubDomains'
response.headers['X-Frame-Options'] = 'DENY'
response.headers['X-Content-Type-Options'] = 'nosniff'
response.headers['X-XSS-Protection'] = '1; mode=block'
return response
# HTTPからHTTPSへのリダイレクト
@app.before_request
def force_https():
if not request.is_secure and request.headers.get('X-Forwarded-Proto') != 'https':
return redirect(request.url.replace('http://', 'https://'))
@app.route('/')
def hello():
return 'Hello HTTPS!'
if __name__ == '__main__':
# SSL証明書の設定
context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
context.load_cert_chain('/etc/letsencrypt/live/example.com/cert.pem',
'/etc/letsencrypt/live/example.com/privkey.pem')
app.run(host='0.0.0.0', port=443, ssl_context=context, debug=False)
SSL/TLSのセキュリティ設定
推奨設定
- TLS 1.2以上のみ:古いプロトコルを無効化
- 強力な暗号スイート:AEAD暗号の使用
- Perfect Forward Secrecy:ECDHE鍵交換の使用
- HSTS:HTTP Strict Transport Securityの有効化
- OCSP Stapling:証明書失効確認の効率化
セキュリティテスト
- SSL Labs:SSL/TLS設定の評価
- testssl.sh:コマンドラインテストツール
- OpenSSL:証明書と接続のテスト
SSL/TLSの診断
OpenSSLコマンド例
# 証明書の確認
openssl x509 -in cert.pem -text -noout
# 証明書の有効期限確認
openssl x509 -in cert.pem -noout -dates
# サーバーの SSL/TLS 設定確認
openssl s_client -connect example.com:443 -servername example.com
# 証明書チェーンの確認
openssl s_client -connect example.com:443 -showcerts
# 特定のプロトコルバージョンのテスト
openssl s_client -connect example.com:443 -tls1_2
openssl s_client -connect example.com:443 -tls1_3
パフォーマンスの最適化
SSL/TLS高速化技術
- Session Resumption:セッションの再利用
- Session Tickets:セッション情報の暗号化保存
- OCSP Stapling:証明書失効確認の最適化
- HTTP/2:多重化による効率化
- TLS 1.3:ハンドシェイクの高速化
CDNの活用
- CloudFlare:無料SSL証明書とパフォーマンス最適化
- AWS CloudFront:AWS Certificate Managerとの統合
- Cloudinary:画像最適化とSSL配信
SSL/TLSの脆弱性
過去の主要な脆弱性
脆弱性 | 年 | 影響 | 対策 |
---|---|---|---|
Heartbleed | 2014 | 秘密鍵の漏洩 | OpenSSL更新 |
POODLE | 2014 | SSL 3.0の脆弱性 | SSL 3.0無効化 |
FREAK | 2015 | 弱い暗号化 | Export暗号無効化 |
Logjam | 2015 | DHE鍵交換の脆弱性 | 強力なDHパラメータ |
証明書の管理
自動化ツール
- Certbot:Let's Encryptの自動取得・更新
- ACME.sh:軽量なACMEクライアント
- AWS Certificate Manager:AWS内での証明書管理
- HashiCorp Vault:PKIシステムとしての活用
証明書の監視
- 有効期限の監視:期限切れ前の通知
- 証明書の変更監視:予期しない変更の検知
- 証明書透明性ログ:不正な証明書の検知
将来の技術動向
- Post-Quantum Cryptography:量子耐性暗号
- TLS 1.4:次世代プロトコル
- Encrypted Client Hello:SNIの暗号化
- QUIC:UDP上のセキュア通信
SSL/TLSのベストプラクティス
- 最新プロトコルの使用:TLS 1.2以上
- 強力な暗号スイート:AEAD暗号の優先
- 定期的な証明書更新:自動化の実装
- セキュリティヘッダー:HSTS等の設定
- 継続的な監視:脆弱性スキャンの実施
関連技術
- HTTPS:HTTP over SSL/TLS
- QUIC:UDP上のセキュア通信
- IPSec:IP層でのセキュア通信
- VPN:仮想プライベートネットワーク