証明書の検証エラー
注:
この記事は、ネットワーク トレースの取得と読み取りに精通しているユーザーを対象としています。
現象
クライアントがサーバー証明書の検証に失敗すると、クライアント アプリケーションに次のエラー メッセージが表示されます。
System.Data.SqlClient.SqlException:
A connection was successfully established with the server, but then an error occurred during the login process.
(provider: SSL Provider, error: 0 - The certificate chain was issued by an authority that is not trusted.)
---> System.ComponentModel.Win32Exception: The certificate chain was issued by an authority that is not trusted
ネットワーク トレースの例
Frame Date and Time Source IP Dest IP Description
----- ------------------- ----------- ----------- -----------------------------------------------------------------------------------
590 8:34:51 AM 3/9/2022 10.10.10.10 10.10.10.20 TCP:Flags=CE....S., SrcPort=56277, DstPort=1433, PayloadLen=0,
593 8:34:51 AM 3/9/2022 10.10.10.20 10.10.10.10 TCP:Flags=.E.A..S., SrcPort=1433, DstPort=56277, PayloadLen=0,
596 8:34:51 AM 3/9/2022 10.10.10.10 10.10.10.20 TCP:Flags=...A...., SrcPort=56277, DstPort=1433, PayloadLen=0,
599 8:34:51 AM 3/9/2022 10.10.10.10 10.10.10.20 TDS:Prelogin, Flags=...AP..., SrcPort=56277, DstPort=1433, PayloadLen=104,
602 8:34:51 AM 3/9/2022 10.10.10.20 10.10.10.10 TDS:Response
605 8:34:51 AM 3/9/2022 10.10.10.10 10.10.10.20 TLS:TLS Rec Layer-1 HandShake: Client Hello.
614 8:34:51 AM 3/9/2022 10.10.10.20 10.10.10.10 TCP:Flags=...A...., SrcPort=1433, DstPort=56277, PayloadLen=0,
617 8:34:51 AM 3/9/2022 10.10.10.20 10.10.10.10 TLS:TLS Rec Layer-1 HandShake: Server Hello. Certificate. Server Key Exchange. Server Hello Done.
686 8:34:51 AM 3/9/2022 10.10.10.10 10.10.10.20 TCP:Flags=...A...F, SrcPort=56277, DstPort=1433, PayloadLen=0,
710 8:34:51 AM 3/9/2022 10.10.10.20 10.10.10.10 TCP:Flags=...A...., SrcPort=1433, DstPort=56277, PayloadLen=0,
713 8:34:51 AM 3/9/2022 10.10.10.20 10.10.10.10 TCP:Flags=...A...F, SrcPort=1433, DstPort=56277, PayloadLen=0,
719 8:34:51 AM 3/9/2022 10.10.10.10 10.10.10.20 TCP:Flags=...A...., SrcPort=56277, DstPort=1433, PayloadLen=0,
コメントを含むネットワーク トレースの例
Frame Date and Time Source IP Dest IP Description
----- ------------------- ----------- ----------- -----------------------------------------------------------------------------------
TCP 3-way handshake establishes a basic TCP connection.
590 8:34:51 AM 3/9/2022 10.10.10.10 10.10.10.20 TCP:Flags=CE....S., SrcPort=56277, DstPort=1433, PayloadLen=0,
593 8:34:51 AM 3/9/2022 10.10.10.20 10.10.10.10 TCP:Flags=.E.A..S., SrcPort=1433, DstPort=56277, PayloadLen=0,
596 8:34:51 AM 3/9/2022 10.10.10.10 10.10.10.20 TCP:Flags=...A...., SrcPort=56277, DstPort=1433, PayloadLen=0,
The PreLogin packet from the client indicates data encryption is required. This also implies the client will try to validate the certificate.
599 8:34:51 AM 3/9/2022 10.10.10.10 10.10.10.20 TDS:Prelogin, Flags=...AP..., SrcPort=56277, DstPort=1433, PayloadLen=104,
- Tds: Prelogin
+ PacketHeader: SPID = 0, Size = 104, PacketID = 1, Window = 0
- PreLoginPacketData:
- PreloginOptions:
+ PreloginOptionTokens:
- PreloginOptionData:
+ VersionData:
- EncryptionData:
Encryption: ENCRYPT_ON 1 (0x1) <----- Data Encryption is Requested by the client
+ InstOptData:
+ ThreadIDData:
+ MARSData:
+ TRACEIDLengthData:
+ FederatedLengthData:
602 8:34:51 AM 3/9/2022 10.10.10.20 10.10.10.10 TDS:Response
The SSL/TLS handshake results in the server sending a certificate to the client.
For data encryption, the client tries to validate the certificate after receiving frame 617 (Server Hello).
605 8:34:51 AM 3/9/2022 10.10.10.10 10.10.10.20 TLS:TLS Rec Layer-1 HandShake: Client Hello.
614 8:34:51 AM 3/9/2022 10.10.10.20 10.10.10.10 TCP:Flags=...A...., SrcPort=1433, DstPort=56277, PayloadLen=0,
617 8:34:51 AM 3/9/2022 10.10.10.20 10.10.10.10 TLS:TLS Rec Layer-1 HandShake: Server Hello. Certificate. Server Key Exchange. Server Hello Done.
- TLS: TLS Rec Layer-1 HandShake: Server Hello. Certificate. Server Key Exchange. Server Hello Done.
- TlsRecordLayer: TLS Rec Layer-1 HandShake:
ContentType: HandShake:
+ Version: TLS 1.2
Length: 847 (0x34F)
- SSLHandshake: SSL HandShake Server Hello Done(0x0E)
HandShakeType: ServerHello(0x02)
Length: 81 (0x51)
+ ServerHello: 0x1
HandShakeType: Certificate(0x0B)
Length: 517 (0x205)
- Cert: 0x1
CertLength: 514 (0x202)
- Certificates:
CertificateLength: 511 (0x1FF)
+ X509Cert: Issuer: SSL_Self_Signed_Fallback, Subject: SSL_Self_Signed_Fallback <---- this is SQL Server's Self-Generated Certificate
HandShakeType: Server Key Exchange(0x0C)
Length: 233 (0xE9)
ServerKeyExchange: Binary Large Object (233 Bytes)
HandShakeType: Server Hello Done(0x0E)
Length: 0 (0x0)
The certificate is an SSL_Self_Signed_Fallback certificate, which means that it cannot be validated.
The client terminates the connection.
686 8:34:51 AM 3/9/2022 10.10.10.10 10.10.10.20 TCP:Flags=...A...F, SrcPort=56277, DstPort=1433, PayloadLen=0,
710 8:34:51 AM 3/9/2022 10.10.10.20 10.10.10.10 TCP:Flags=...A...., SrcPort=1433, DstPort=56277, PayloadLen=0,
713 8:34:51 AM 3/9/2022 10.10.10.20 10.10.10.10 TCP:Flags=...A...F, SrcPort=1433, DstPort=56277, PayloadLen=0,
719 8:34:51 AM 3/9/2022 10.10.10.10 10.10.10.20 TCP:Flags=...A...., SrcPort=56277, DstPort=1433, PayloadLen=0,
注:
この例では、自己生成証明書を使用するSQL Serverを示していますが、何らかの理由でクライアントから信頼されていない場合は、任意の証明書がサーバー Hello パケットに含まれる可能性があります。
説明
ネットワーク トレースを確認して、クライアントとサーバー間の通信フローを理解します。
- フレーム 590 から 599: データ暗号化を示す TCP ハンドシェイクと PreLogin パケットが必要です。
- フレーム 605 - 617: サーバー証明書を送信する Server Hello との TLS ハンドシェイク。
- フレーム 686 - 719: 証明書検証エラーによる接続の終了。
クライアントは、サーバー証明書の検証をトリガーするデータ暗号化を要求します。 ただし、サーバーは自己署名証明書 (SSL_Self_Signed_Fallback
) を送信して応答します。これにより、検証が失敗します。
クライアントがデータ暗号化 (Encrypt=yes
または) を要求した場合、または Use Encryption for Data=True
サーバーでデータ暗号化 (Force Encryption=Yes
新しいドライバーのみ) が必要な場合、クライアント ドライバーはサーバー証明書の検証を試みます。
注:
暗号化が要求されない場合、PreLogin パケットは引き続き暗号化されますが、証明書は検証されません。
サーバー証明書を検証するには、クライアントのコンピューター証明書ストアに、サーバー証明書、信頼されたルート証明書、または信頼された中間証明書のコピーが含まれている必要があります。
サード パーティの証明機関 (CA) から証明書を購入すると、通常、Windows にはルート証明書がプレインストールされ、何もする必要はありません。
会社に CA がある場合は、グループ ポリシー経由でルート証明書または中間証明書をプッシュアウトするか、手動で追加する必要があります。
自己署名証明書があり、必要なクライアントの数が少ない場合は、通常、手動で追加する必要があります。 ただし、クライアントの数が多い場合は、グループ ポリシーを使用して証明書を配布できます。 セキュリティのために秘密キーなしでSQL Serverからエクスポートします。
SQL Serverが証明書を使用しない場合は、それ自体に対して証明書が生成されます。
軽減策
短期的な軽減策: アプリケーションの接続文字列で設定TrustServerCertificate=Yes
します。
長期的な軽減策: サーバーの証明書を購入または生成します。