VB.NET Core(.NET 6/7/8)デスクトップアプリから SQL Server 2022 へ安全に接続するには、ドライバの既定(Encrypt=既定で有効)を理解し、開発と本番で接続文字列と証明書の扱いを切り分けるのが最短ルートです。この記事では Microsoft.Data.SqlClient 6.0.2 を前提に、開発での最小構成から本番の TLS 運用、証明書導入と検証、トラブル対処までを一気通貫で解説します。
前提とゴール
- クライアント:VB.NET Core デスクトップアプリ(WinForms/WPF いずれも可)、
Microsoft.Data.SqlClient 6.0.2利用。 - サーバー:SQL Server 2022(Windows 版)。
- 目的:暗号化(TLS)を前提に、開発環境では最小手数で動かし、本番では正しい証明書検証まで通す。
質問の整理(要約)
- 開発用 PC では次の接続文字列で十分か?
Server=localhost;Database=CombinedCommands;Trusted_Connection=True;TrustServerCertificate=True - 本番では SQL Server にサーバー証明書を必ず導入すべきか?
- 証明書の導入手順は?
結論(先に答え)
- 開発:上記の接続文字列で概ね十分。
Encryptは既定で有効、TrustServerCertificate=Trueにより検証をスキップして素早く疎通確認が可能。ただし機密データは置かないこと。 - 本番:必ずサーバー証明書を導入して CA チェーンで検証。接続文字列は
Encrypt=True(既定)かつTrustServerCertificate=False(既定)で、証明書の CN/SAN とサーバー名が一致すれば検証に成功する。可能ならEncrypt=Strict(5.1+)でさらに厳格化。 - 手順:①CA でサーバー認証用証明書を発行(CN/SAN に FQDN を含める)→②サーバーの ローカル コンピューター 個人ストアへインポート→③SQL Server 構成マネージャーで証明書を選択→④サービス再起動→⑤クライアントで検証。
シナリオ別の推奨設定(早見表)
| シナリオ | 推奨接続文字列/設定 | ポイント |
|---|---|---|
| 開発・テスト | Server=localhost;Database=CombinedCommands;Trusted_Connection=True;TrustServerCertificate=True | Windows 認証で素早く接続。暗号化はされるが真正性検証は省略。外部ネットワークに出さず、機密データを置かない。 |
| 本番(標準) | Server=db01.contoso.local;Database=CombinedCommands;Encrypt=True;TrustServerCertificate=False;Integrated Security=True | サーバー証明書必須。Encrypt は既定で True、TrustServerCertificate は既定で False。CN/SAN と接続先名が一致していること。 |
| 本番(SQL 認証) | Server=db01.contoso.local;Database=CombinedCommands;User Id=app_user;Password=***;Encrypt=True;TrustServerCertificate=False | 資格情報は安全に保管。運用では接続文字列への平文パスワードは避け、OS シークレットや DPAPI、Azure Key Vault 等を併用。 |
| より厳格に | Encrypt=Strict(ドライバ 5.1+) | 中間者攻撃耐性を強化。信頼されない証明書や自己署名を拒否。可能なら本番は Strict を推奨。 |
なぜ「TrustServerCertificate=True」は開発限定なのか
TrustServerCertificate=True は「暗号化はするが、サーバー証明書の正当性(誰が発行し、誰に対して発行されたか)を検証しない」モードです。LAN 内でもルーティングやプロキシ誤設定で第三者の偽装証明書に乗り換わる余地がゼロではありません。本番では CA による検証を通し、サーバー名と証明書の一致(CN/SAN)を満たす構成にしてください。
SQL Server 側の TLS 設計ポイント
- サーバー証明書の EKU は必ず「Server Authentication」。
- 鍵長は RSA 2048 以上を推奨(運用標準に合わせて 3072/4096 でも可)。
- TLS 1.0/1.1 は無効化し、TLS 1.2 を最低ラインにする(OS のポリシーで統制)。
- CN/SAN はクライアントが接続文字列で指定する「名前」と一致させる(FQDN を推奨)。IP で接続したい場合は SAN に IP を含める。
- 証明書は ローカル コンピューター の「個人(My)」ストアに「秘密鍵付き」で格納する。
証明書要件(まとめ表)
| 項目 | 要件 | メモ |
|---|---|---|
| 用途(EKU) | Server Authentication(1.3.6.1.5.5.7.3.1) | クライアント認証のみの証明書は不可。 |
| CN/SAN | FQDN(例:db01.contoso.local)を必ず含める | 別名(CNAME)で接続するなら、その別名も SAN に追加。 |
| 鍵長/アルゴリズム | RSA 2048 以上 | 運用標準に従う。互換性面から RSA 推奨。 |
| キー用途 | Digital Signature / Key Encipherment | KeySpec は KeyExchange を満たすのが無難。 |
| 配置ストア | ローカル コンピューター > 個人(My) | ユーザーストアでは SQL Server サービスが参照できない。 |
| 秘密鍵 | 必須(サーバー側) | 鍵付きでインポート(PFX)。 |
証明書の導入手順(詳細)
1. 証明書を発行する
商用 CA もしくは社内 CA(AD CS)から「サーバー認証」証明書を取得します。CSR を使う場合は以下のような INF を用意します。
; request.inf(例:FQDN を SAN に追加)
[Version]
Signature="$Windows NT$"
[NewRequest]
Subject = "CN=db01.contoso.local"
KeyLength = 2048
KeySpec = 1
KeyUsage = 0xa0
Exportable = TRUE
MachineKeySet = TRUE
ProviderName = "Microsoft RSA SChannel Cryptographic Provider"
SMIME = FALSE
PrivateKeyArchive = FALSE
HashAlgorithm = sha256
RequestType = PKCS10
[Extensions]
2.5.29.17 = "{text}"
*continue* = "dns=db01.contoso.local&"
*continue* = "dns=sql.contoso.local" ; 別名がある場合
2.5.29.37 = "{text}"
*continue* = "1.3.6.1.5.5.7.3.1" ; Server Authentication
作成したら certreq -new request.inf request.req で CSR を作成し、CA に提出して署名済みの .cer(もしくは秘密鍵付きの .pfx)を受領します。開発用に自己署名を使う場合は、一時利用に限り PowerShell で発行できます。
New-SelfSignedCertificate `
-DnsName "db01.contoso.local" `
-FriendlyName "SQL Server Dev" `
-CertStoreLocation "Cert:\LocalMachine\My" `
-KeyLength 2048 -KeyExportPolicy Exportable `
-KeyUsage DigitalSignature,KeyEncipherment `
-TextExtension @("2.5.29.37={text}1.3.6.1.5.5.7.3.1")
自己署名は開発限定。本番では CA 発行を必須にしてください。
2. サーバーへインポート
- サーバー上で証明書(PFX)をダブルクリックし、ローカル コンピューター の「個人(My)」ストアへインポート。中間/ルートも合わせて「中間証明機関」「信頼されたルート証明機関」に配置。
- 証明書スナップイン(
certlm.msc)で、対象証明書に鍵アイコンが表示されていること(秘密鍵あり)を確認。
3. SQL Server 構成マネージャーで証明書を選択
- 「SQL Server 構成マネージャー」→「SQL Server ネットワークの構成」→「プロトコル」→対象インスタンスを開く。
- 「証明書」タブでインポートした証明書を選択。
- 「フラグ」タブで必要に応じて「暗号化の強制(Force Encryption)」を「はい」に設定(サーバー側で常に暗号化を強制)。
- SQL Server サービスを再起動。
4. クライアントの信頼を整える
- クライアント OS に中間/ルート証明書を配布(GPO、MDM、構成管理ツール等)。
- 接続文字列に FQDN を指定(
Server=db01.contoso.local)。CNAME を使う場合はその別名も SAN に含める。
接続文字列レシピ集(.NET 6/7/8 + SqlClient 6.0.2)
| 目的 | 接続文字列 | 解説 |
|---|---|---|
| 開発(Windows 認証) | Server=localhost;Database=CombinedCommands;Trusted_Connection=True;TrustServerCertificate=True | 最小手間で動かす。Trusted_Connection=True は Integrated Security=True と同義。 |
| 本番(Windows 認証) | Server=db01.contoso.local;Database=CombinedCommands;Encrypt=True;TrustServerCertificate=False;Integrated Security=True | 既定の暗号化を活かし、検証を有効のまま(False)。 |
| 本番(SQL 認証) | Server=db01.contoso.local;Database=CombinedCommands;User Id=app_user;Password=***;Encrypt=True;TrustServerCertificate=False | 資格情報は OS シークレットや安全なストアに。 |
| 厳格モード | ...;Encrypt=Strict;TrustServerCertificate=False | ドライバ 5.1+ で有効。検証失敗は即エラー。 |
| 可用性グループ(AG) | Server=listener.contoso.local;Database=CombinedCommands;Encrypt=True;MultiSubnetFailover=True | リスナー名に SAN を付与。フェールオーバー高速化。 |
| 名前の不一致を解決 | ...;HostNameInCertificate=db01.contoso.local | 証明書の名前と接続先表記が合わない場合の最終手段。基本は SAN を正す。 |
VB.NET の接続コード例(検証クエリ付き)
Imports Microsoft.Data.SqlClient
Module Program
Sub Main()
Dim cs As String =
"Server=db01.contoso.local;" &
"Database=CombinedCommands;" &
"Encrypt=True;" &
"TrustServerCertificate=False;" &
"Integrated Security=True;" &
"Connect Timeout=15;"
Using cn As New SqlConnection(cs)
cn.Open()
' 暗号化状態をサーバー側で確認
Using cmd As New SqlCommand("SELECT encrypt_option FROM sys.dm_exec_connections WHERE session_id = @@SPID;", cn)
Dim enc As String = CStr(cmd.ExecuteScalar())
Console.WriteLine($"encrypt_option = {enc}") ' TRUE であれば TLS で暗号化
End Using
Console.WriteLine("TLS 接続に成功しました。")
End Using
End Sub
End Module
検証手順(サーバー側・クライアント側)
サーバー側
- SQL Server ログに「証明書の読み込み」メッセージが出ているか確認。
SELECT ... FROM sys.dm_exec_connectionsのencrypt_optionがTRUEになっているか。- 構成マネージャーで「証明書」タブに対象証明書が表示されているか。
クライアント側
- 接続先は FQDN を使用(
ping db01.contoso.localで名前解決を確認)。 sqlcmdでの検証:sqlcmd -S db01.contoso.local -d CombinedCommands -E -N(-Nは暗号化必須、-Cは検証スキップなので本番では使わない)。- 証明書チェーンが OS に信頼されているか(中間/ルートは正しいストアに入っているか)。
自己署名証明書の扱い
- 開発限定で可。全クライアントに発行元(自己署名または社内 CA)を配布・信頼させる必要がある。
- 本番では CA 発行に切り替える。運用コストとセキュリティの両面で優位。
パフォーマンスへの影響
TLS は CPU を使用しますが、現行ハードウェアでは OLTP 規模で数%程度に収まることが一般的です。証明書検証のオーバーヘッドは初回接続時に限定され、接続プーリング後の命令実行にはほぼ影響しません。
「よくあるつまずき」と対処集
| 症状/メッセージ(例) | 主原因 | 対処 |
|---|---|---|
| The certificate chain was issued by an authority that is not trusted. | 中間/ルートがクライアント側で信頼されていない | 中間/ルート証明書を正しいストアに配布。GPO/MDM を活用。 |
| A connection was successfully established…, but then an error occurred during the login process (provider: SSL Provider) | 証明書の EKU/用途不一致、鍵なし、期限切れ | EKU=Server Authentication、秘密鍵付き、未失効・未期限切れを確認。 |
| Hostname mismatch | CN/SAN と接続先名が一致しない | 証明書の SAN に FQDN を追加し再発行。暫定的に HostNameInCertificate で回避可。 |
| 開発では動くが本番で失敗 | 開発は TrustServerCertificate=True のため検証を通過していた | 本番は CA 発行証明書に切替え、TrustServerCertificate=False で接続。 |
| Integrated Security でのみ失敗 | Kerberos(SPN)や DNS の不整合 | SPN(MSSQLSvc/fqdn:port)を確認。FQDN で接続。 |
| 動的ポートで接続できない | SQL Browser が停止/遮断 | 既定の 1433 を固定するか、SQL Browser を起動/ファイアウォールを調整。 |
Linux / macOS クライアントの注意点
- SqlClient は OS の OpenSSL/証明書ストアを利用。CA チェーンは
/etc/ssl/certs等に正しくインストールする。 - Windows 統合認証を使う場合は Kerberos 設定(
krb5.conf、KDC、SPN)が必要。難度が高いため、まずは SQL 認証で疎通確認し、段階的に移行するのが無難。
セキュリティ強化チェックリスト
- サーバー側「暗号化の強制(Force Encryption)」を有効化。
- クライアントは
Encrypt=True(既定)を維持、可能ならEncrypt=Strict。 - TLS 1.0/1.1 を無効化し、TLS 1.2 を最低ラインに(OS ポリシーで統制)。
- 証明書の失効確認(CRL/OCSP)が機能しているか。
- 接続文字列から平文パスワードを排除(秘密情報は安全なストアへ)。
運用のコツ(証明書ライフサイクル)
- 有効期限の 30〜60 日前に自動通知し、事前に再発行・切替を計画。
- 切替時は旧/新証明書の並行配置 → 構成マネージャーで新証明書を選択 → サービス再起動 → 検証。
- 可用性グループや複数インスタンスでは、各ノードに同じ方針で配布(CN/SAN は各ノードで適切に)。
高度な話題(必要に応じて)
- HostNameInCertificate:一部の互換性問題で証明書名が変えられない場合、接続側で期待ホスト名を明示可能。ただし根本解決は SAN の是正。
- Always Encrypted:転送中の TLS 暗号化に加え、列単位の暗号化(鍵はクライアント管理)。機微データでは検討価値が高い。
- 接続回復性:
ConnectRetryCountとConnectRetryIntervalを利用し、瞬断に強くする。
FAQ(よくある疑問)
Q. 開発ではどの接続文字列が最短?
A. Server=localhost;Database=...;Trusted_Connection=True;TrustServerCertificate=True。
Q. 本番で証明書は必須?
A. はい。CA 発行のサーバー証明書を導入し、検証を通す構成が必須です。
Q. 導入手順は?
A. CA で発行 → サーバーに PFX を ローカル コンピューター 個人ストアへ → 構成マネージャーで選択 → 再起動 → クライアントで検証。
まとめ
SqlClient 6.0.2 では暗号化が既定で有効になり、接続文字列の Encrypt=True を明示しなくても TLS は動作します。しかし安全な本番運用の核心は「検証をスキップしない」ことです。FQDN と一致する CA 発行証明書を SQL Server に導入し、クライアントは TrustServerCertificate=False のまま接続する—これが最小リスクで最大効果のベストプラクティスです。開発では利便性を優先しつつ、本番への移行フェーズで早めに CA 証明書に切り替えて挙動を確認し、障害の少ないリリースを実現しましょう。
付録:チェックリスト(貼って使える)
- 接続先は FQDN を使っているか(CNAME/別名も SAN に含めたか)。
- 証明書はローカル コンピューター個人ストアに秘密鍵付きで入っているか。
- EKU=Server Authentication、鍵長は 2048 以上か。
- SQL Server 構成マネージャーで証明書を選択し、「暗号化の強制」が必要に応じて有効か。
- クライアントの中間/ルートは信頼済みか。
sys.dm_exec_connections.encrypt_optionが TRUE か。- AG/リスナー名の SAN は正しいか。
- (Windows 認証時)SPN は正しく登録されているか。
付録:最小動作 VB.NET スニペット(開発)
Imports Microsoft.Data.SqlClient
Module DevConnect
Sub Main()
Dim cs As String =
"Server=localhost;" &
"Database=CombinedCommands;" &
"Trusted_Connection=True;" &
"TrustServerCertificate=True"
Using cn As New SqlConnection(cs)
cn.Open()
Console.WriteLine("Dev: 接続 OK(検証はスキップ中)")
End Using
End Sub
End Module
付録:本番用テンプレート(差し替え欄つき)
; <serverFQDN> と <dbName> を置換
Server=<serverFQDN>;Database=<dbName>;Encrypt=True;TrustServerCertificate=False;Integrated Security=True;Application Name=MyDesktopApp;

コメント