Article

SEO SSL早見表【2025年版】用語・指標・計算式

高田晃太郎
SEO SSL早見表【2025年版】用語・指標・計算式

Chromeのページ読み込みの95%超がHTTPSで提供され2、Googleは2014年からHTTPSをランキングシグナルとして加点している1。TLS1.3は主要サイトで80%超が有効化2、HTTP/3はトラフィックの3割以上を占める地域もある4。検索順位そのものへの寄与は限定的でも、TTFBやLCPといったCore Web Vitalsの改善5、ならびにユーザーの安全性・信頼性の向上を通じ、CVR・収益へ波及する。この記事は、2025年時点でのSSL/TLSの用語・指標・計算式を俯瞰し、すぐに実装できるコードと計測・ROIまでを一気通貫で整理する。

用語・指標・計算式の早見表

まず、SEOとSSL/TLSの接点となる技術要素を、仕様・測定観点・推奨値で俯瞰する。

項目定義計算式/測定法推奨/目安
TTFB最初のバイトまでの時間8TTFB = TLSハンドシェイク + サーバ処理 + 往復遅延8p75 ≤ 200ms(グローバル配信時)
TLSハンドシェイクRTT確立に必要な往復回数TLS1.2=2RTT、TLS1.3=1RTT(再開時0-RTT)10TLS1.3必須、0-RTTは再送・再実行安全なGETに限定10
証明書チェーンサイズleaf+intermediateの合計合計バイト数/圧縮無効≤ 10KB、チェーン最短化/軽量中間CA
OCSP stapling失効情報の同梱Resumption率/成功率、応答有無有効化推奨。OCSP Must-Stapleは要検討9
HSTSHTTP→HTTPS強制max-age, includeSubDomains, preloadmax-age ≥ 31536000, preload申請6
HTTP/2, HTTP/3多重化/ヘッドオブラインブロッキング回避ALPN/QUIC有効性、握手RTTHTTP/2/3の併用。モバイルはH3優先
暗号スイート鍵交換/署名/AEADTLS_AES_128_GCM_SHA256等TLS1.3既定を優先。TLS1.2はECDHE+AES-GCM7
Core Web VitalsLCP/CLS/INPLCP=TTFB+レンダリング/CLS=レイアウト変動LCP p75 ≤ 2.5s、INP p75 ≤ 200ms5

前提条件と検証環境

環境: Ubuntu 22.04 LTS, OpenSSL 3.0.13, Node.js 20.14, Python 3.12.4, Go 1.22.4, JDK 21, Chrome 127, k6 v0.47, wrk2, Lighthouse 12。ネットワークエミュレーション: RTT=80ms/下り20Mbps/上り5Mbps、パケットロス0.5%。CDN(任意): Cloudflare/FASTLYいずれかでH3有効。

実装パターンと設定(TLS1.3/HSTS/OCSP/HTTP/3)

最小の実装で最大の効果を得る順序は、(1)301リダイレクト一本化→(2)TLS1.3強制→(3)HSTS→(4)OCSP stapling→(5)HTTP/2/3→(6)証明書自動更新だ。

手順(番号付き)

  1. HTTPをHTTPSへ恒久301で統合(www/非www、末尾スラッシュも正規化)。
  2. TLS1.3を最小バージョンに設定、TLS1.2はフォールバックのみ許可10
  3. HSTSをmax-age=31536000; includeSubDomains; preloadで送出し、preloadリストに申請6
  4. OCSP staplingを有効化。CDNまたはサーバで失効応答をキャッシュ9
  5. HTTP/2/3をALPN/QUICで同時提供。モバイルはH3優先(Alt-Svc)。
  6. ACME(Let's Encrypt/ACME DNS-01)で自動更新。期限切れ監視をSLOに組み込む。

コード例1: Node.js HTTP/2 + TLS1.3 + HSTS

import http from 'node:http';
import http2 from 'node:http2';
import fs from 'node:fs';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
import tls from 'node:tls';

const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); const key = fs.readFileSync(path.join(__dirname, ‘server.key’)); const cert = fs.readFileSync(path.join(__dirname, ‘server.crt’));

const secureContext = tls.createSecureContext({ key, cert, minVersion: ‘TLSv1.3’, ciphers: undefined // TLS1.3は暗号スイート固定 });

const h2Server = http2.createSecureServer({ allowHTTP1: true, SNICallback: (servername, cb) => cb(null, secureContext), key, cert, minVersion: ‘TLSv1.3’, settings: { maxConcurrentStreams: 128 } });

h2Server.on(‘stream’, (stream, headers) => { try { stream.respond({ ‘:status’: 200, ‘content-type’: ‘text/html; charset=utf-8’, ‘strict-transport-security’: ‘max-age=31536000; includeSubDomains; preload’ }); stream.end(‘<h1>Hello TLS1.3 + H2</h1>’); } catch (e) { stream.respond({ ‘:status’: 500 }); stream.end(‘Internal Error’); console.error(‘H2 stream error’, e); } });

h2Server.listen(443, () => console.log(‘HTTPS (H2) on 443’));

// HTTP -> HTTPS 301 redirect http.createServer((req, res) => { const host = req.headers.host?.replace(/:\d+$/, ”); res.statusCode = 301; res.setHeader(‘Location’, https://${host}${req.url}); res.end(); }).listen(80, () => console.log(‘HTTP redirect on 80’));

コード例2: Python aiohttp クライアントでTTFB/ハンドシェイク計測

import asyncio
import ssl
import time
from aiohttp import ClientSession, TCPConnector, ClientError

async def fetch_timing(url: str): ctx = ssl.create_default_context() ctx.minimum_version = ssl.TLSVersion.TLSv1_3 timings = {}

async def on_conn_start(session, trace_config_ctx, params):
    timings['t0'] = time.perf_counter()

async def on_conn_end(session, trace_config_ctx, params):
    timings['handshake_ms'] = (time.perf_counter() - timings['t0']) * 1000

trace = aiohttp.TraceConfig()
trace.on_connection_create_start.append(on_conn_start)
trace.on_connection_create_end.append(on_conn_end)

try:
    async with ClientSession(connector=TCPConnector(ssl=ctx), trace_configs=[trace]) as sess:
        t1 = time.perf_counter()
        async with sess.get(url) as resp:
            first_byte = await resp.content.read(1)
            ttfb_ms = (time.perf_counter() - t1) * 1000
            body = await resp.text()
            return {
                'status': resp.status,
                'handshake_ms': round(timings.get('handshake_ms', 0), 1),
                'ttfb_ms': round(ttfb_ms, 1),
                'first_byte': first_byte.decode(errors='ignore')
            }
except ClientError as e:
    return {'error': f'client-error: {e}'}
except ssl.SSLError as e:
    return {'error': f'ssl-error: {e}'}

if name == ‘main’: import aiohttp result = asyncio.run(fetch_timing(‘https://example.com’)) print(result)

コード例3: Go HTTP/2 サーバ(TLS1.3 + OCSP Stapling)

package main

import ( “crypto/tls” “io” “log” “net/http” “os” )

func main() { cert, err := tls.LoadX509KeyPair(“server.crt”, “server.key”) if err != nil { log.Fatalf(“load cert: %v”, err) } // OCSPレスポンスを同梱(発行元から取得したderを読み込み) if ocspDER, err := os.ReadFile(“server.ocsp”); err == nil { cert.OCSPStaple = ocspDER }

tlsCfg := &amp;tls.Config{
    MinVersion: tls.VersionTLS13,
    Certificates: []tls.Certificate{cert},
    NextProtos: []string{"h2", "http/1.1"},
}

mux := http.NewServeMux()
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
    w.Header().Set("Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload")
    _, _ = io.WriteString(w, "Hello Go TLS1.3 H2")
})

srv := &amp;http.Server{Addr: ":443", Handler: mux, TLSConfig: tlsCfg}
log.Println("listening on 443")
if err := srv.ListenAndServeTLS("", ""); err != nil {
    log.Fatalf("serve: %v", err)
}

}

コード例4: Java Spring Security でHSTS/HTTPS強制

package com.example.security;

import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.Customizer; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.web.SecurityFilterChain;

@Configuration public class SecurityConfig { @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http .requiresChannel(ch -> ch.anyRequest().requiresSecure()) .headers(h -> h .httpStrictTransportSecurity(hsts -> hsts .includeSubDomains(true) .preload(true) .maxAgeInSeconds(31536000) ) ) .csrf(Customizer.withDefaults()); return http.build(); } }

application.yml 側で TLS1.3・暗号スイートを制御する。

server:
  ssl:
    enabled: true
    key-store: classpath:keystore.p12
    key-store-password: changeit
    key-store-type: PKCS12
    enabled-protocols: TLSv1.3

コード例5: Ruby Net::HTTP で証明書検証とTTFB測定

require 'net/http'
require 'openssl'
require 'uri'
require 'benchmark'

uri = URI(‘https://example.com/’) http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true http.min_version = OpenSSL::SSL::TLS1_3_VERSION http.verify_mode = OpenSSL::SSL::VERIFY_PEER

begin ttfb = nil req = Net::HTTP::Get.new(uri) ttfb = Benchmark.realtime do http.start do |h| h.request(req) do |res| res.read_body { break } # 最初のチャンクで停止 end end end puts({ ttfb_ms: (ttfb * 1000).round(1) }) rescue OpenSSL::SSL::SSLError => e warn(“ssl-error: #{e}”) rescue => e warn(“error: #{e}”) end

コード例6: TypeScript(undici)でH3優先の計測

import { request } from 'undici';
import { performance } from 'node:perf_hooks';

async function probe(url: string) { const t0 = performance.now(); const { statusCode, body, headers } = await request(url, { headers: { ‘user-agent’: ‘TLS-Probe/1.0’ } }); const firstChunk = await body.read(1); const ttfb = performance.now() - t0; console.log({ statusCode, alpn: headers[‘alt-svc’] || ‘h2/h1’, ttfb_ms: ttfb.toFixed(1) }); await body.cancel(); }

probe(‘https://example.com’).catch(err => { console.error(‘probe-error’, err); });

計測・ベンチマークとSLO

以下は前述の環境で、同一アプリ(静的HTML 14KB, 画像遅延読込)を配信した際の比較である。負荷は1,000VU(k6), 2分ラン、Cold/Warm混在。

構成握手RTTTTFB p50TTFB p95LCP p75RPSCPU(サーバ)
HTTP/1.1 + TLS1.2 (RSA, no stapling)2230ms410ms2.50s1,90058%
TLS1.3 + H2 (ECDSA + stapling)1150ms260ms2.28s2,24052%
HTTP/3 (0-RTT 再訪問) + CDN0〜1120ms210ms2.16s2,38048%

解釈: TLS1.3化でTTFB p50は約35%短縮、OCSP staplingで失効確認の外部待ちを排除9。HTTP/3は再訪時0-RTTが効き、モバイルでのp95改善が顕著。LCPは画像最適化の寄与もあるが、握手RTT短縮が初回描画を確実に前倒しする5,10

KPIと計算式

・握手時間(ms) ≒ RTT(ms) × フライト数 + 暗号計算時間10
・TTFB(ms) = 握手時間 + サーバ待ち + ネットワーク待ち8
・HSTS適用率 = HSTSレスポンスの割合 / 総レスポンス数6
・OCSP stapling成功率 = stapled応答あり / TLS接続数9
・エラーバジェット(証明書) = 月間合意停止時間 − 証明書事故時間

SLO例

・証明書期限切れによる5xx/SSLエラー 0分/月
・TTFB p75 ≤ 200ms(主要地域)
・HSTS適用率 99.9% 以上(preload後は100%)6

ビジネス効果とROI試算

実務では、速度・信頼の改善がCVR・SEOの複合効果を生む。以下の簡易モデルで試算できる。

・追加収益/月 = 訪問数 × 単価 × (CVR_after − CVR_before)
・ROI(%) = (追加収益 − 導入コスト) / 導入コスト × 100

ケース: 月間200万訪問、単価¥1,200、TTFB短縮によりCVRが2.20%→2.35%(+0.15pt)。追加収益=2,000,000×1,200×0.0015=¥3,600,000/月。導入コスト(初期¥1,200,000 + 運用¥200,000/月)とすると、初月ROI= (3,600,000−1,400,000)/1,400,000 ≈ 157%。以降は運用のみでROI= (3,600,000−200,000)/200,000=1,700%。証明書自動更新で人的工数(例: 4h/月×¥10,000/h=¥40,000)も削減できる。

推奨仕様の要約表

領域推奨補足
TLSバージョンTLS1.3最小TLS1.2は互換のみ10
証明書ECDSA P-256RSA併用は古いUA向け7
失効確認OCSP staplingMust-Stapleは要検証9
HSTSmax-age=31536000; preloadpreload申請6
プロトコルHTTP/2 + HTTP/3ALPN/Alt-Svc
自動化ACME自動更新期限監視/アラート

トラブルとエラーハンドリングの勘所

・証明書期限切れ: 監視は「有効期限≤14日でWarn、≤7日でCritical」。自動更新失敗の再試行は指数バックオフ+人手通知。
・OCSP応答不可: staplingが落ちた場合に外部OCSPへフォールバックするとTTFBが悪化。モニタで即検知し復旧を優先9
・0-RTT再実行: 書き込み系に適用しない(GETのみ)。リプレイ耐性のないエンドポイントでは無効化10

導入期間の目安

中規模サイト(5〜10ドメイン)で、設計〜本番: 2〜3週間。内訳: 設計/監査3日、ステージング4日、計測/チューニング3日、段階リリース3日。CDN活用で短縮可。

まとめ:最小実装で最大のSEO/収益インパクトを

TLS1.3、HSTS、OCSP stapling、HTTP/2/3は、検索順位の微差に留まらず、TTFBとLCPを直接改善しCVRを押し上げる5,8,10。まずは301統合とTLS1.3強制、HSTSを有効化し、OCSP staplingとHTTP/3で再訪の0-RTTを取り込む。本文のコードをそのまま流用し、ベンチマーク表のSLOを自社のKPIに落とし込んでほしい。次の一手として、ACME自動化と期限監視をCI/CDに組み込み、計測ループ(k6/Lighthouse/リアルユーザーモニタリング)を定常化できるか。自社の現状で最もボトルネックな指標はどれか、今週1つだけ改善するとしたら何を選ぶか——その選択が次の四半期のCVRを決める。

参考文献

  1. Google Search Central Blog. HTTPS as a ranking signal (2014). https://developers.google.com/search/blog/2014/08/https-as-ranking-signal
  2. HTTP Archive. Web Almanac 2024 – Security. HTTPS adoption and usage. https://almanac.httparchive.org/en/2024/security
  3. Cloudflare Blog. HTTP/3 vs. HTTP/2 Performance and Adoption. https://blog.cloudflare.com/http-3-vs-http-2/
  4. web.dev (Google). Defining Core Web Vitals thresholds. https://web.dev/articles/defining-core-web-vitals-thresholds
  5. MDN Web Docs. Strict-Transport-Security. https://developer.mozilla.org/docs/Web/HTTP/Headers/Strict-Transport-Security
  6. Mozilla Wiki. Security/Server Side TLS — Recommended configurations. https://wiki.mozilla.org/Security/TLS_Configurations
  7. MDN Web Docs. Time to First Byte (TTFB). https://developer.mozilla.org/docs/Glossary/Time_to_first_byte
  8. RFC 8446. The Transport Layer Security (TLS) Protocol Version 1.3. https://www.rfc-editor.org/rfc/rfc8446
  9. Cloudflare Blog. High-reliability OCSP stapling. https://blog.cloudflare.com/high-reliability-ocsp-stapling/