SSL/TLS

API | IT用語集

この用語をシェア

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 ハンドシェイク

  1. Client Hello:クライアントが対応する暗号スイートを送信
  2. Server Hello:サーバーが暗号スイートを選択して送信
  3. Certificate:サーバーがSSL証明書を送信
  4. Server Key Exchange:必要に応じて追加の鍵情報を送信
  5. Server Hello Done:サーバーがハンドシェイクの完了を通知
  6. Client Key Exchange:クライアントが暗号化された鍵を送信
  7. Change Cipher Spec:暗号化通信の開始を通知
  8. 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:仮想プライベートネットワーク

関連Webサイト

この用語についてもっと詳しく

SSL/TLSに関するご質問や、システム導入のご相談など、お気軽にお問い合わせください。

カテゴリ

API IT用語集