<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>openssl s_client | 徒然なるままに</title>
	<atom:link href="https://www.seichan.org/tag/openssl-s_client/feed" rel="self" type="application/rss+xml" />
	<link>https://www.seichan.org</link>
	<description>徒然と日々の出来事(ネタ)を書いていこうかと．主に FreeBSD，Unix系の話題が中心ですが，その他の話題もあつかってみたり．</description>
	<lastBuildDate>Thu, 08 Oct 2026 21:52:50 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.1.2</generator>
	<item>
		<title>【証明書入門 第7回】TLSの仕組み ― TLS 1.3のハンドシェイク・暗号スイート・SNI/ECH・mTLS・PQC</title>
		<link>https://www.seichan.org/2026/10/cert-07-tls.html</link>
					<comments>https://www.seichan.org/2026/10/cert-07-tls.html#respond</comments>
		
		<dc:creator><![CDATA[seichan]]></dc:creator>
		<pubDate>Thu, 08 Oct 2026 21:00:00 +0000</pubDate>
				<category><![CDATA[証明書・PKI]]></category>
		<category><![CDATA[ECH]]></category>
		<category><![CDATA[mTLS]]></category>
		<category><![CDATA[openssl s_client]]></category>
		<category><![CDATA[PQC]]></category>
		<category><![CDATA[SNI]]></category>
		<category><![CDATA[TLS]]></category>
		<category><![CDATA[TLS 1.3]]></category>
		<category><![CDATA[暗号スイート]]></category>
		<guid isPermaLink="false">https://www.seichan.org/blog/?p=6778</guid>

					<description><![CDATA[証明書が実際の通信でどう使われるか、TLSの仕組みを解説します。SSLからTLS 1.3までの歴史と古い方式が禁止された理由、TLS 1.3のハンドシェイクとメッセージの役割、TLS 1.2との違い、暗号スイートの読み方、SNI・ALPN・ECH、セッション再開と0-RTT、mTLS、PQCハイブリッド鍵交換、推奨設定、s_client・curl・PowerShellでの調べ方まで。]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">「nginxで<code>ssl_ciphers</code>を絞ったのに、TLS 1.3の暗号スイートが変わらないんです」<br>「新しいブラウザーにしたら、古いプロキシーの先のサイトにつながらなくなりました」</p>



<p class="wp-block-paragraph">TLSは、ここ数年で大きく変わりました。TLS 1.3の登場、古い方式の禁止、SNIの暗号化（ECH）、そして耐量子計算機暗号（PQC）の導入。仕組みが変わったことを知らないと、こうした「設定したのに変わらない」「急につながらない」の原因にたどり着けません。</p>



<p class="wp-block-paragraph">第6回までで、証明書の中身と発行の流れを見てきました。第7回では、その証明書が<strong>実際の通信でどう使われるか</strong>、<strong>TLSの仕組み</strong>を見ていきます。</p>


<div class=".for-sp">
<div id="im-5078de7a65f140ac9d12a50b8ac9ee9c">
  <script async src="https://imp-adedge.i-mobile.co.jp/script/v1/spot.js?20220104"></script>
  <script>(window.adsbyimobile=window.adsbyimobile||[]).push({pid:81546,mid:567719,asid:1946055,type:"banner",display:"inline",elementid:"im-5078de7a65f140ac9d12a50b8ac9ee9c"})</script>
</div>
</div>

<div class=".for-pc">
<!-- admax -->
<script src="https://adm.shinobi.jp/s/8ae3a18ff526e95e579f5814fddd88f6"></script>
<!-- admax -->
<!--
<div id="im-3931cf74888b4888ae5fb170df744749">
  <script async src="https://imp-adedge.i-mobile.co.jp/script/v1/spot.js?20220104"></script>
  <script>(window.adsbyimobile=window.adsbyimobile||[]).push({pid:81546,mid:567718,asid:1946233,type:"banner",display:"inline",elementid:"im-3931cf74888b4888ae5fb170df744749"})</script>
</div>
-->
</div>



<hr class="wp-block-separator has-alpha-channel-opacity"/>




  <div id="toc" class="toc tnt-number toc-center tnt-number border-element"><input type="checkbox" class="toc-checkbox" id="toc-checkbox-1" checked><label class="toc-title" for="toc-checkbox-1">目次</label>
    <div class="toc-content">
    <ol class="toc-list open"><li><a href="#toc1" tabindex="0">SSLからTLS 1.3まで</a></li><li><a href="#toc2" tabindex="0">古い方式が使えなくなった理由</a></li><li><a href="#toc3" tabindex="0">TLS 1.3のハンドシェイク</a><ol><li><a href="#toc4" tabindex="0">メッセージの役割</a></li></ol></li><li><a href="#toc5" tabindex="0">TLS 1.2（ECDHE）との違い</a></li><li><a href="#toc6" tabindex="0">暗号スイートの読み方（1.2と1.3）</a></li><li><a href="#toc7" tabindex="0">SNI・ALPN・ECH</a></li><li><a href="#toc8" tabindex="0">セッション再開と0-RTT</a></li><li><a href="#toc9" tabindex="0">クライアント証明書（mTLS）</a></li><li><a href="#toc10" tabindex="0">PQCハイブリッド鍵交換（X25519MLKEM768）</a></li><li><a href="#toc11" tabindex="0">推奨設定（RFC 9325とMozillaの設定例）</a></li><li><a href="#toc12" tabindex="0">接続を調べる：openssl s_client</a><ol><li><a href="#toc13" tabindex="0">s_clientの主なオプション</a></li></ol></li><li><a href="#toc14" tabindex="0">curlとWindows（PowerShell）で調べる</a></li><li><a href="#toc15" tabindex="0">考えてみよう</a></li><li><a href="#toc16" tabindex="0">まとめ</a></li><li><a href="#toc17" tabindex="0">連載「証明書入門」全11回</a></li></ol>
    </div>
  </div>

<h2 class="wp-block-heading"><span id="toc1">SSLからTLS 1.3まで</span></h2>



<figure class="wp-block-table"><table><thead><tr><th>バージョン</th><th>公開</th><th>仕様</th><th>現在の扱い</th></tr></thead><tbody><tr><td>SSL 2.0</td><td>1995年</td><td>Netscape の仕様</td><td>使用禁止（RFC 6176、2011年）</td></tr><tr><td>SSL 3.0</td><td>1996年</td><td>RFC 6101（歴史的記録）</td><td>使用禁止（RFC 7568、2015年）。POODLE</td></tr><tr><td>TLS 1.0</td><td>1999年</td><td>RFC 2246</td><td>使用禁止（RFC 8996、2021年）</td></tr><tr><td>TLS 1.1</td><td>2006年</td><td>RFC 4346</td><td>使用禁止（RFC 8996、2021年）</td></tr><tr><td>TLS 1.2</td><td>2008年</td><td>RFC 5246</td><td>使用可。ECDHE と AEAD に限る</td></tr><tr><td>TLS 1.3</td><td>2018年</td><td>RFC 8446 で標準化、2026年7月に RFC 9846 へ改訂</td><td>推奨。新しいプロトコルは TLS 1.3 必須（RFC 9852）</td></tr></tbody></table></figure>



<p class="wp-block-paragraph">RFC 8996は「MUST NOT（使ってはならない）」で、「非推奨」ではありません。RFC 9846はTLS 1.2の仕様（RFC 5246）なども廃止扱いにし、TLS 1.2の実装への要件を引き継ぎました。<strong>TLS 1.2の使用が禁止されたわけではありません</strong>。この記事ではTLS 1.3をRFC 9846として扱います。</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading"><span id="toc2">古い方式が使えなくなった理由</span></h2>



<p class="wp-block-paragraph">SSL・TLSの歴史は、<strong>見つかった弱点を塞いできた歴史</strong>です。</p>



<figure class="wp-block-image size-large"><img decoding="async" src="https://www.seichan.org/blog/wp-content/uploads/2026/09/cert07-s084.png" alt="1995年のSSL 2.0から2018年のTLS 1.3までのバージョンの登場と、BEAST・POODLE攻撃、SSL 3.0・RC4・TLS 1.0/1.1の禁止、2026年のTLS 1.2のRSA鍵交換・DHEの禁止までの年表"/></figure>



<ul class="wp-block-list">
<li><strong>SSL 3.0</strong>：パディングの検査の甘さを突いて平文を割り出す<strong>POODLE攻撃</strong>（2014年）で致命傷を負った</li>


<li><strong>TLS 1.0</strong>：CBCモードの弱点を突く<strong>BEAST攻撃</strong>（2011年）があった</li>


<li><strong>TLS 1.0と1.1</strong>：認証付き暗号（AEAD）を使えず、SHA-1にも頼っていたため、2021年のRFC 8996で使用禁止に。暗号ではRC4も2015年に禁止された</li>


<li><strong>2026年7月のRFC 10015</strong>：TLS 1.2でも、<strong>RSA鍵交換と有限体のDH（DHE）鍵交換が使用禁止</strong>になった。RSA鍵交換には前方秘匿性（第2回）がなく、サーバーの秘密鍵が後で漏れると、記録されていた過去の通信がすべて解読されるから</li>
</ul>



<p class="wp-block-paragraph">結果として、<strong>TLS 1.2で使ってよいのはECDHEとAEADの組み合わせにほぼ限られ</strong>、TLS 1.3と同じ考え方になりました。今使うのは、<strong>TLS 1.3と、TLS 1.2（ECDHE＋AEAD）</strong>です。</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading"><span id="toc3">TLS 1.3のハンドシェイク</span></h2>



<p class="wp-block-paragraph">TLS 1.3では、ハンドシェイクが<strong>1往復（1-RTT）</strong>で終わります。</p>



<figure class="wp-block-image size-large"><img decoding="async" src="https://www.seichan.org/blog/wp-content/uploads/2026/09/cert07-s085.png" alt="クライアントがkey_share（X25519MLKEM768）・SNI・ALPNを含むClientHelloを送り、サーバーがServerHello（key_share）を返した時点から暗号化が始まり、EncryptedExtensions・Certificate・CertificateVerify・Finishedを暗号化して送り、クライアントのFinishedの後にアプリケーションデータを送る1往復のハンドシェイクを示す図"/></figure>



<ol class="wp-block-list">
<li>クライアントは<strong>ClientHello</strong>で、対応する暗号スイートや署名方式、接続先の名前（SNI）に加え、<strong>鍵交換の材料（key_share）を最初から送る</strong>。選ばれそうな方式を予想して入れておく</li>


<li>サーバーは<strong>ServerHello</strong>で方式を選び、自分のkey_shareを返す。<strong>この時点で両者は同じ秘密を計算でき、以降は暗号化される</strong></li>


<li>続けて証明書（Certificate）、秘密鍵による署名（CertificateVerify）、Finishedなどを<strong>暗号化して</strong>送る</li>


<li>クライアントは証明書を検証し（第5回）、Finishedを返してデータを送り始める</li>
</ol>



<p class="wp-block-paragraph"><strong>証明書も暗号化されて届く</strong>ため、途中の機器からは中身が見えません。予想が外れると、サーバーがHelloRetryRequestで方式を指定し、1往復増えます。<strong>最初の1通に鍵の材料を入れるから、2通目から暗号化できる</strong>わけです。</p>



<h3 class="wp-block-heading"><span id="toc4">メッセージの役割</span></h3>



<figure class="wp-block-table"><table><thead><tr><th>メッセージ</th><th>向き</th><th>暗号化</th><th>役割</th></tr></thead><tbody><tr><td>ClientHello</td><td>C→S</td><td>なし</td><td>対応するバージョン・暗号スイート・グループ・署名方式、key_share、SNI、ALPN</td></tr><tr><td>ServerHello</td><td>S→C</td><td>なし</td><td>選んだ暗号スイートとグループ、サーバーの key_share</td></tr><tr><td>EncryptedExtensions</td><td>S→C</td><td>あり</td><td>ALPN の結果など、暗号化してよい拡張</td></tr><tr><td>CertificateRequest</td><td>S→C</td><td>あり</td><td>クライアント証明書を求める（mTLS のときだけ）</td></tr><tr><td>Certificate</td><td>S→C</td><td>あり</td><td>サーバー証明書と中間証明書</td></tr><tr><td>CertificateVerify</td><td>S→C</td><td>あり</td><td>ここまでのやり取りへの署名。証明書の秘密鍵を持つことの証明</td></tr><tr><td>Finished</td><td>双方向</td><td>あり</td><td>やり取り全体の MAC。途中で改ざんされていないことの確認</td></tr><tr><td>NewSessionTicket</td><td>S→C</td><td>あり</td><td>次回の再開用のチケット</td></tr></tbody></table></figure>



<p class="wp-block-paragraph">TLS 1.3では、<strong>証明書の秘密鍵は鍵交換に使われず</strong>、CertificateVerifyで「この証明書の持ち主が、今このやり取りをしている」ことを示す<strong>署名にだけ</strong>使われます。鍵交換は毎回使い捨てのECDHEで行うため、証明書の秘密鍵が後で漏れても過去の通信は解読されません（前方秘匿性）。</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading"><span id="toc5">TLS 1.2（ECDHE）との違い</span></h2>



<figure class="wp-block-image size-large"><img decoding="async" src="https://www.seichan.org/blog/wp-content/uploads/2026/09/cert07-s087.png" alt="TLS 1.2（ECDHE）はClientHelloからFinishedまで2往復で暗号化が始まり証明書が平文で流れるのに対し、TLS 1.3は1往復で、ServerHelloの後から証明書も暗号化されることを並べて比べた図"/></figure>



<p class="wp-block-paragraph">TLS 1.2のECDHEによるハンドシェイクは<strong>2往復</strong>です。TLS 1.3との違いは3つあります。</p>



<ol class="wp-block-list">
<li>鍵交換の材料を2往復目に送るため、<strong>遅い</strong></li>


<li><strong>証明書が平文で流れる</strong>。同じ証明書でも、1.2では途中の機器から中身が見える</li>


<li><strong>古い方式を選べてしまう</strong></li>
</ol>



<p class="wp-block-paragraph">よく見かける「プリマスターシークレットをサーバーの公開鍵で暗号化して送る」という図は、<strong>RSA鍵交換</strong>の図です。前方秘匿性がないためTLS 1.3で廃止され、TLS 1.2でもRFC 10015で禁止されました。TLS 1.2を残すなら、<strong>ECDHEとAEADの暗号スイートだけを許可</strong>します。</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading"><span id="toc6">暗号スイートの読み方（1.2と1.3）</span></h2>



<figure class="wp-block-table"><table><thead><tr><th>項目</th><th>TLS 1.2</th><th>TLS 1.3</th></tr></thead><tbody><tr><td>例（IANA の名前）</td><td>TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256</td><td>TLS_AES_128_GCM_SHA256</td></tr><tr><td>例（OpenSSL の名前）</td><td>ECDHE-RSA-AES128-GCM-SHA256</td><td>TLS_AES_128_GCM_SHA256（同じ）</td></tr><tr><td>名前が表すもの</td><td>鍵交換（ECDHE）・認証（RSA）・暗号（AES-128-GCM）・ハッシュ</td><td>暗号（AEAD）とハッシュだけ</td></tr><tr><td>鍵交換の決め方</td><td>暗号スイートで決まる</td><td>supported_groups・key_share 拡張（X25519MLKEM768 等）</td></tr><tr><td>署名の決め方</td><td>暗号スイート＋signature_algorithms</td><td>signature_algorithms 拡張</td></tr><tr><td>種類</td><td>数百（古いものを含む）</td><td>5つ（主に使うのは3つ）</td></tr><tr><td>OpenSSL・nginx での設定</td><td>-cipher、ssl_ciphers</td><td>-ciphersuites、ssl_conf_command Ciphersuites</td></tr></tbody></table></figure>



<p class="wp-block-paragraph">TLS 1.3で主に使うのは、AES-128-GCM・AES-256-GCM・ChaCha20-Poly1305の3つです。</p>



<p class="wp-block-paragraph">冒頭の「<code>ssl_ciphers</code>を絞ったのに変わらない」の答えがここにあります。<strong>nginxの<code>ssl_ciphers</code>はTLS 1.2以前の設定で、TLS 1.3の暗号スイートは変わりません</strong>。TLS 1.3は<code>ssl_conf_command Ciphersuites</code>で設定します。Windowsでは<code>Get-TlsCipherSuite</code>で、有効な暗号スイートと順序を確認できます。</p>


<div class=".for-sp">
<div id="im-c929b2770f964f7f88505b9ee7500db9">
  <script async src="https://imp-adedge.i-mobile.co.jp/script/v1/spot.js?20220104"></script>
  <script>(window.adsbyimobile=window.adsbyimobile||[]).push({pid:81546,mid:567719,asid:1946057,type:"banner",display:"inline",elementid:"im-c929b2770f964f7f88505b9ee7500db9"})</script>
</div>
</div>

<div class=".for-pc">
<!-- admax -->
<script src="https://adm.shinobi.jp/s/a1cf34f40c7d6f1acda2feeee1bc3a16"></script>
<!-- admax -->
<!--
<div id="im-3b5a2348efcc4b7a9435e1334f6172f2">
  <script async src="https://imp-adedge.i-mobile.co.jp/script/v1/spot.js?20220104"></script>
  <script>(window.adsbyimobile=window.adsbyimobile||[]).push({pid:81546,mid:567718,asid:1946056,type:"banner",display:"inline",elementid:"im-3b5a2348efcc4b7a9435e1334f6172f2"})</script>
</div>
-->
</div>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading"><span id="toc7">SNI・ALPN・ECH</span></h2>



<ul class="wp-block-list">
<li><strong>SNI（Server Name Indication）</strong>：ClientHelloで接続したい名前を伝える拡張。複数のサイトを動かすサーバーは、SNIを見て返す証明書を選ぶ</li>


<li><strong>ALPN</strong>：HTTP/2（h2）とHTTP/1.1のどちらを使うかを決める拡張</li>
</ul>



<figure class="wp-block-image size-large"><img decoding="async" src="https://www.seichan.org/blog/wp-content/uploads/2026/09/cert07-s089.png" alt="ECHなしではClientHelloのSNI（shop.example.jp）が平文で途中の機器に見えて振り分けや記録に使われるが、ECHありではDNSのHTTPSレコードから得た公開鍵で本当のClientHelloを暗号化し、外側には共通の名前public.example.netだけを見せることを示す図"/></figure>



<p class="wp-block-paragraph">ただし<strong>SNIは平文</strong>なので、途中の機器から接続先が見えます。これを隠すのが<strong>ECH（Encrypted Client Hello、RFC 9849、2026年3月）</strong>です。</p>



<ul class="wp-block-list">
<li>クライアントは、DNSのHTTPSレコード（連載「DNS入門」第6回）からECHの公開鍵を得て、<strong>本当のClientHelloを暗号化</strong>し、外側には共通の名前だけを見せる</li>


<li>Chromeは117、Firefoxは119から既定で有効</li>
</ul>



<p class="wp-block-paragraph">注意したいのは、<strong>SNIで振り分けや監視をする社内のプロキシーやファイアウォールは、ECHの通信を見分けられなくなる</strong>ことです。</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading"><span id="toc8">セッション再開と0-RTT</span></h2>



<p class="wp-block-paragraph">フルのハンドシェイクは時間がかかるため、一度接続した相手とは、前回の結果を使って<strong>短い手順で再接続</strong>します。</p>



<figure class="wp-block-image size-large"><img decoding="async" src="https://www.seichan.org/blog/wp-content/uploads/2026/09/cert07-s090.png" alt="初回はフルハンドシェイクでNewSessionTicketを受け取り、再開時はチケット（PSK）で証明書なしに短縮し、0-RTTでは最初の1通で早期データも送るが、攻撃者が記録して送り直すリプレイで同じ注文が2回処理されうることを示す図"/></figure>



<ul class="wp-block-list">
<li>TLS 1.2ではセッションIDやセッションチケット、TLS 1.3ではNewSessionTicketで渡されるチケット（<strong>PSK、事前共有鍵</strong>）を使う。TLS 1.3ではPSKと新しいECDHEを組み合わせて、前方秘匿性も保てる</li>


<li>注意点は、チケットを暗号化するサーバー側の鍵（<strong>チケットキー</strong>）。長く変えずにいて漏れると多くの通信が解読されるため、<strong>定期的に入れ替える</strong></li>
</ul>



<p class="wp-block-paragraph">さらにTLS 1.3には、再開時にClientHelloと一緒に最初のデータを送る<strong>0-RTT（早期データ）</strong>があります。速くなる代わりに、<strong>記録した早期データを送り直すリプレイ攻撃を防げず</strong>、同じ「注文」が2回処理されるおそれがあります。0-RTTは既定で無効のサーバーが多く、使うなら<strong>副作用のない処理に限ります</strong>。迷ったら無効のままにしましょう。</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading"><span id="toc9">クライアント証明書（mTLS）</span></h2>



<p class="wp-block-paragraph">サーバーがCertificateRequestを送り、クライアントも証明書と署名（CertificateVerify）を返して<strong>互いに認証する</strong>方式を、<strong>相互TLS（mTLS、クライアント証明書認証）</strong>と呼びます。</p>



<figure class="wp-block-image size-large"><img decoding="async" src="https://www.seichan.org/blog/wp-content/uploads/2026/09/cert07-s091.png" alt="社内CAがクライアント証明書を発行・配布し、サーバーがCertificateRequestで証明書を求め、クライアントも証明書とCertificateVerifyを返し、サーバーが社内CAのルートで検証して鍵を持つ端末だけを通すことを示す図"/></figure>



<ul class="wp-block-list">
<li>通常のTLSと違い、<strong>秘密鍵を持つ端末だけが接続できる</strong>ため、パスワードを盗まれても使えない</li>


<li>802.1X（EAP-TLS）、VPN、サービス間のAPI通信などで使い、証明書は<strong>社内CA（第9回）で発行するのが基本</strong></li>


<li>以前は公開CAの証明書にもクライアント認証の用途（EKUのclientAuth）が入っていたが、Chromeのルートプログラムの要件の変更で、<strong>Let&#8217;s Encryptは2026年2月にこれを外した</strong>。流用している構成は見直す</li>


<li>TLS 1.3はRSAのPKCS#1 v1.5署名を認めないが、古いICカードなどのため、2026年4月のRFC 9963でクライアント証明書に限り例外が設けられた</li>
</ul>



<p class="wp-block-paragraph">サーバー証明書と同じ確認を、逆向きにもう1回行う、と考えると分かりやすいでしょう。</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading"><span id="toc10">PQCハイブリッド鍵交換（X25519MLKEM768）</span></h2>



<p class="wp-block-paragraph">冒頭の2つ目、「新しいブラウザーで古いプロキシーの先につながらない」の原因になりうるのが、これです。</p>



<figure class="wp-block-image size-large"><img decoding="async" src="https://www.seichan.org/blog/wp-content/uploads/2026/09/cert07-s092.png" alt="従来のX25519とFIPS 203のML-KEM-768の2つの秘密を混ぜてセッション鍵を作り片方が破られても安全であることと、ClientHelloのkey_shareがX25519の32バイトからX25519MLKEM768の約1,216バイトに増えて1パケットに収まらず古い機器で失敗することがあることを示す図"/></figure>



<p class="wp-block-paragraph">量子コンピューターが実用化されるとECDHEやRSAは解かれるおそれがあり、今の通信を記録して将来解読する「Harvest Now, Decrypt Later」攻撃に備えて、<strong>鍵交換から移行</strong>が進んでいます（第2回）。</p>



<ul class="wp-block-list">
<li>使われるのは、従来のX25519と、FIPS 203のML-KEM-768を組み合わせる<strong>X25519MLKEM768</strong>（RFC 10024、2026年8月）。両方を混ぜて鍵を作るため、<strong>片方が破られても安全</strong></li>


<li>Chrome 131、Firefox 132、iOS・macOS 26、OpenSSL 3.5が<strong>既定で提示</strong>する。WindowsのSchannelも2026年に対応したが既定では無効</li>


<li>注意点は、<strong>key_shareが約1.2KB増えて、ClientHelloが1パケットに収まらなくなる</strong>こと。これを扱えない古い機器やミドルボックスでは、接続に失敗する</li>
</ul>



<p class="wp-block-paragraph">変わったのは鍵交換だけで、<strong>証明書の署名は今もECDSAやRSA</strong>です。</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading"><span id="toc11">推奨設定（RFC 9325とMozillaの設定例）</span></h2>



<figure class="wp-block-table"><table><thead><tr><th>項目</th><th>Modern</th><th>Intermediate（一般的な推奨）</th></tr></thead><tbody><tr><td>TLS バージョン</td><td>1.3 のみ</td><td>1.2、1.3</td></tr><tr><td>TLS 1.3 の暗号スイート</td><td>AES-128-GCM、AES-256-GCM、ChaCha20-Poly1305</td><td>同左</td></tr><tr><td>TLS 1.2 の暗号スイート</td><td>—</td><td>ECDHE＋AES-GCM／ChaCha20-Poly1305 の6つだけ</td></tr><tr><td>鍵交換のグループ</td><td>X25519MLKEM768、X25519、P-256、P-384</td><td>同左</td></tr><tr><td>証明書</td><td>ECDSA（P-256・P-384）</td><td>ECDSA、または RSA 2048ビット以上</td></tr><tr><td>HSTS</td><td>max-age=63072000（2年）</td><td>同左</td></tr><tr><td>想定する最も古いクライアント</td><td>Chrome 70、Firefox 63、Android 10、Safari 12.1</td><td>IE 11（Windows 10）、Android 4.4.2、Java 8u161</td></tr></tbody></table></figure>



<p class="wp-block-paragraph"><strong>Mozilla SSL Configuration Generator</strong>（ssl-config.mozilla.org、ガイドライン 6.0）は、nginx・Apache等の設定例をサーバーのバージョンに合わせて出してくれます。<strong>迷ったらIntermediate</strong>を選びます。RFC 9325（2022年）はTLS 1.2以上を必須・TLS 1.3を推奨とし、RFC 9852（2026年）は新しいプロトコルにTLS 1.3を必須としました。</p>


<div class=".for-sp">
<div id="im-e200ff972f7b43fe9c8c2a7b60698c08">
  <script async src="https://imp-adedge.i-mobile.co.jp/script/v1/spot.js?20220104"></script>
  <script>(window.adsbyimobile=window.adsbyimobile||[]).push({pid:81546,mid:567719,asid:1946060,type:"banner",display:"inline",elementid:"im-e200ff972f7b43fe9c8c2a7b60698c08"})</script>
</div>
</div>

<div class=".for-pc">
<!-- admax -->
<script src="https://adm.shinobi.jp/s/b379fcf4fc1a53eab29cb4ffbda7f14f"></script>
<!-- admax -->
<!--
<div id="im-4f0e910e1dca4503a73e8d9a2678879f">
  <script async src="https://imp-adedge.i-mobile.co.jp/script/v1/spot.js?20220104"></script>
  <script>(window.adsbyimobile=window.adsbyimobile||[]).push({pid:81546,mid:567718,asid:1946059,type:"banner",display:"inline",elementid:"im-4f0e910e1dca4503a73e8d9a2678879f"})</script>
</div>
-->
</div>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading"><span id="toc12">接続を調べる：openssl s_client</span></h2>



<pre class="wp-block-code"><code>$ openssl s_client -connect www.example.jp:443 -servername www.example.jp &lt;/dev/null
（抜粋）
Certificate chain
 0 s:CN=www.example.jp
   i:C=JP, O=Example Trust, CN=Example Issuing CA
   a:PKEY: EC, (prime256v1); sigalg: ecdsa-with-SHA256
   v:NotBefore: Jul 29 22:10:08 2026 GMT; NotAfter: Oct 27 22:17:21 2026 GMT
 1 s:C=JP, O=Example Trust, CN=Example Issuing CA
   i:C=JP, O=Example Trust, CN=Example Root CA
Negotiated TLS1.3 group: X25519MLKEM768
Verification: OK
New, TLSv1.3, Cipher is TLS_AES_256_GCM_SHA384
    Verify return code: 0 (ok)</code></pre>



<ul class="wp-block-list">
<li><strong><code>-servername</code>を必ず付ける</strong>（SNI）。付けないと既定の証明書が返り、名前の不一致と誤解する</li>


<li>Certificate chain：0がサーバー証明書、1以降が中間証明書。各行のi:（発行者）が次の番号のs:（主体）とつながっているかを見る（第4回）。v:で有効期間も分かる</li>


<li><code>Verification: OK</code>は、手元の信頼ストアでチェーンの検証に成功したという意味。<strong>名前の一致は既定では確かめない</strong>ので、<code>-verify_hostname www.example.jp</code>を付ける。失敗すると<code>10 (certificate has expired)</code>のように番号と理由が出る（第10回）</li>
</ul>



<h3 class="wp-block-heading"><span id="toc13">s_clientの主なオプション</span></h3>



<figure class="wp-block-table"><table><thead><tr><th>やりたいこと</th><th>オプション・コマンド</th><th>見るところ</th></tr></thead><tbody><tr><td>名前の一致も検証する</td><td>-verify_hostname www.example.jp</td><td>Verified peername:、不一致は 62 (hostname mismatch)</td></tr><tr><td>バージョンを指定して試す</td><td>-tls1_2／-tls1_3</td><td>接続できるか、Protocol:</td></tr><tr><td>鍵交換のグループを指定する</td><td>-groups X25519MLKEM768</td><td>Negotiated TLS1.3 group:</td></tr><tr><td>ALPN を送る</td><td>-alpn h2,http/1.1</td><td>ALPN protocol: h2</td></tr><tr><td>送られたチェーンを PEM で全部見る</td><td>-showcerts</td><td>中間証明書が送られているか</td></tr><tr><td>要約だけ見る</td><td>-brief</td><td>Protocol version:、Ciphersuite:</td></tr><tr><td>メールの STARTTLS</td><td>-starttls smtp（imap・pop3 等）</td><td>メールサーバーの証明書</td></tr><tr><td>期限と SAN だけ見る</td><td>s_client の出力をパイプで openssl x509 -noout -dates -ext subjectAltName に渡す</td><td>notAfter と SAN</td></tr></tbody></table></figure>



<p class="wp-block-paragraph"><code>-tls1_2</code>で接続すると、ECDHEの鍵交換は<code>Peer Temp Key: X25519, 253 bits</code>のように表示されます。OpenSSL 3は既定のセキュリティレベルでTLS 1.0/1.1を送らないため、<code>-tls1_1</code>は手元で「no protocols available」になり、<strong>サーバーの設定は分かりません</strong>。サーバーが受け付ける版の一覧は、次のnmapなどで調べます。</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading"><span id="toc14">curlとWindows（PowerShell）で調べる</span></h2>



<pre class="wp-block-code"><code>$ curl -v -o /dev/null https://www.example.jp/        # （抜粋）
* ALPN: curl offers h2,http/1.1
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384 / X25519MLKEM768 / id-ecPublicKey
* ALPN: server accepted h2
* Server certificate:
*   subject: CN=www.example.jp
*   expire date: Oct 27 22:17:21 2026 GMT
*   subjectAltName: &quot;www.example.jp&quot; matches cert&#x27;s &quot;www.example.jp&quot;
* SSL certificate verified via OpenSSL.</code></pre>



<pre class="wp-block-code"><code>PS&gt; $tcp = [System.Net.Sockets.TcpClient]::new(&#x27;www.example.jp&#x27;, 443)
PS&gt; $ssl = [System.Net.Security.SslStream]::new($tcp.GetStream())
PS&gt; $ssl.AuthenticateAsClient(&#x27;www.example.jp&#x27;)     # 検証（名前を含む）に失敗すると例外
PS&gt; $ssl.SslProtocol                                # Tls13
PS&gt; $ssl.NegotiatedCipherSuite                      # TLS_AES_256_GCM_SHA384（PowerShell 7）
PS&gt; ([System.Security.Cryptography.X509Certificates.X509Certificate2]$ssl.RemoteCertificate).NotAfter
PS&gt; $ssl.Dispose(); $tcp.Dispose()</code></pre>



<ul class="wp-block-list">
<li><code>Test-NetConnection www.example.jp -Port 443</code>は、<strong>TCPの到達性だけ</strong>を見る。TLSと証明書は上のSslStreamで確かめる</li>


<li>PowerShell 7なら<code>Invoke-WebRequest https://www.example.jp -SslProtocol Tls12</code>で、指定した版で接続できるかを試せる</li>


<li>サーバーが受け付ける版と暗号スイートの一覧は<code>nmap --script ssl-enum-ciphers -p 443 www.example.jp</code>で取れる（<strong>許可を得た対象にだけ</strong>使う）</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading"><span id="toc15">考えてみよう</span></h2>



<ol class="wp-block-list">
<li>自分の担当サーバーは、TLS 1.0/1.1やRSA鍵交換（TLS_RSA_WITH_…）の暗号スイートをまだ受け付けていませんか。どうやって確かめますか。</li>


<li>社内のプロキシーやファイアウォールは、SNIを見て通信を制御していますか。ECHや大きなClientHello（PQC）が広がると、何が起きそうですか。</li>


<li>クライアント証明書（mTLS）を使っている仕組みはありますか。その証明書はどのCAが発行し、失効はどう確かめていますか。</li>
</ol>



<p class="wp-block-paragraph"><strong>ヒント</strong>：この記事の「古い方式が使えなくなった理由」「SNI・ALPN・ECH」「mTLS」「PQCハイブリッド鍵交換」と、確認コマンドが手がかりです。</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading"><span id="toc16">まとめ</span></h2>



<ul class="wp-block-list">
<li>今使うのは<strong>TLS 1.3</strong>と<strong>TLS 1.2（ECDHE＋AEAD）</strong>。RSA鍵交換は2026年に1.2でも禁止</li>


<li>TLS 1.3は<strong>1往復</strong>で暗号化が始まり、<strong>証明書も暗号化</strong>される。証明書の秘密鍵は<strong>署名にだけ</strong>使う</li>


<li>TLS 1.3の暗号スイートは<strong>AEADとハッシュだけ</strong>。nginxの<code>ssl_ciphers</code>では変わらない</li>


<li><strong>SNIは平文、ECHで暗号化</strong>。SNIを見る社内の機器に影響する</li>


<li><strong>0-RTTはリプレイを防げない</strong>。mTLSの証明書は<strong>社内CA</strong>で発行する</li>


<li>PQCの<strong>X25519MLKEM768</strong>は既定で使われ始めた。<strong>大きなClientHello</strong>で古い機器が失敗しうる</li>
</ul>



<p class="wp-block-paragraph">次回は、証明書の<strong>期限切れを防ぐ</strong>ための棚卸し、<strong>ACMEによる自動更新</strong>、期限の監視を扱います。</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading"><span id="toc17">連載「証明書入門」全11回</span></h2>



<ol class="wp-block-list">
<li><a href="https://www.seichan.org/2026/10/cert-01-why.html" target="_blank">なぜ証明書が必要か</a></li>


<li><a href="https://www.seichan.org/2026/10/cert-02-crypto-basics.html" target="_blank">暗号の基礎</a></li>


<li><a href="https://www.seichan.org/2026/10/cert-03-hands-on.html" target="_blank">openssl・PowerShellで試す</a></li>


<li><a href="https://www.seichan.org/2026/10/cert-04-x509.html" target="_blank">X.509証明書の中身</a></li>


<li><a href="https://www.seichan.org/2026/10/cert-05-pki-trust.html" target="_blank">PKIと信頼の仕組み</a></li>


<li><a href="https://www.seichan.org/2026/10/cert-06-issuance.html" target="_blank">証明書の種類と発行</a></li>


<li><strong>TLSの仕組み（この記事）</strong></li>


<li>ライフサイクルと自動化</li>


<li>社内PKIとクラウド</li>


<li>証明書トラブルシュート</li>


<li>証明書の設計演習</li>
</ol>
]]></content:encoded>
					
					<wfw:commentRss>https://www.seichan.org/2026/10/cert-07-tls.html/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
