MeWrite Docs

SSL: handshake failed

SSLハンドシェイクエラーの解決方法

概要

SSL/TLS接続のハンドシェイク処理が失敗した場合に発生するエラーです。

エラーメッセージ

SSL: error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure

または

curl: (35) SSL connect error

原因

  1. プロトコル不一致: クライアントとサーバーのTLSバージョン不一致
  2. 証明書問題: 期限切れ、不正な証明書
  3. 暗号スイート: 共通の暗号スイートがない
  4. SNI未対応: Server Name Indicationの問題

解決策

1. TLSバージョン確認

1
2
3
4
5
6
# サーバーのTLSバージョン確認
openssl s_client -connect example.com:443 -tls1_2
openssl s_client -connect example.com:443 -tls1_3

# 詳細情報
curl -v https://example.com

2. Nginx設定

1
2
3
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
ssl_prefer_server_ciphers on;

3. Node.js設定

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
const https = require('https');

const options = {
  hostname: 'example.com',
  port: 443,
  minVersion: 'TLSv1.2',
  rejectUnauthorized: true
};

https.get(options, (res) => {
  // ...
});

4. Python設定

1
2
3
4
5
6
7
import ssl
import urllib.request

context = ssl.create_default_context()
context.minimum_version = ssl.TLSVersion.TLSv1_2

response = urllib.request.urlopen('https://example.com', context=context)

5. デバッグ方法

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# 詳細なハンドシェイク情報を確認
openssl s_client -connect example.com:443 -debug

# 使用可能な暗号スイートを確認
openssl ciphers -v

# サーバーがサポートする暗号スイートを確認
nmap --script ssl-enum-ciphers -p 443 example.com

# SNI(Server Name Indication)を明示
openssl s_client -connect example.com:443 -servername example.com

6. curl での詳細診断

1
2
3
4
5
6
7
8
# 詳細なSSL情報を表示
curl -v --tlsv1.2 https://example.com

# 特定のTLSバージョンを強制
curl --tlsv1.3 https://example.com

# 暗号スイートを指定
curl --ciphers 'ECDHE-RSA-AES128-GCM-SHA256' https://example.com

7. Apache設定

1
2
3
SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1
SSLCipherSuite ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256
SSLHonorCipherOrder on

よくある間違い

  • 古いTLSバージョンへのフォールバック許可
  • 自己署名証明書の検証無効化

関連エラー

SSL/TLS の他のエラー

最終更新: 2025-12-09