首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> 關於.NET

WCF 安全性實戰:X.509 憑證驗證完整指南

     編輯:關於.NET

WCF 傳輸安全三大支柱

  • 訊息完整性:確保傳輸過程未被竄改,通常透過數位簽章實現。
  • 訊息機密性:防止第三方窺探內容,採用非對稱加密演算法。
  • 雙向驗證:客戶端與服務端互相驗證身分,阻擋偽裝與 DoS 攻擊。

X.509 憑證核心概念

X.509 是 ITU-T 制定的數位憑證標準,基於公開金鑰基礎建設(PKI)。每張憑證包含一對金鑰:

  • 公開金鑰:公開分發,用於加密資料或驗證簽章。
  • 私有金鑰:嚴格保密,用於解密或產生簽章。

流程:客戶端用伺服器的公開金鑰加密敏感資料(如帳密),伺服器用私鑰解密。只有持有私鑰者能解密,確保機密性。

為何選擇 X.509 而非 UserName/Password?

特性UserName/PasswordX.509 Certificate
驗證開銷需查詢資料庫比對,延遲較高本機憑證存儲比對序號/指紋,極快
部署複雜度低,僅需帳號管理較高,需憑證發行、部署、存儲管理
適用場景B/S 系統、內部員工系統B2B、高安全性要求、跨網域服務

完整 Demo 實作步驟

1. 建立自我簽署憑證

使用 Visual Studio Developer Command Prompt:

makecert -r -pe -n "CN=MyServer" -ss My -sky exchange
makecert -r -pe -n "CN=Client" -ss My -sky exchange

分別產生伺服器與客戶端憑證,安裝至「個人」存儲區。記下客戶端憑證的序號(Serial Number),供服務端驗證使用。

建立憑證 查看序號

2. 方案結構

Solution 結構
  • WCFValidationContract:定義 Service Contract(介面)
  • WCFValidationServices:實作服務邏輯與自訂驗證器
  • WCFValidationHost:Console/WinForm 宿主啟動服務
  • WCFValidationClient:客戶端呼叫程式

3. 服務契約與實作

[ServiceContract]
public interface IX509
{
    [OperationContract]
    bool Test();
}

public class X509Service : IX509
{
    public bool Test() => true;
}

4. 自訂憑證驗證器

public class X509Validator : X509CertificateValidator
{
    public override void Validate(X509Certificate2 certificate)
    {
        // 僅允許特定序號的客戶端憑證
        const string allowedSerial = "6bfa829a7453219e402c534671154e4e";
        if (certificate.SerialNumber.ToLower() != allowedSerial)
            throw new SecurityTokenValidationException("Invalid client certificate.");
    }
}

5. 服務端組態

<system.serviceModel>
  <behaviors>
    <serviceBehaviors>
      <behavior name="X509Behavior">
        <serviceMetadata httpGetEnabled="true" httpGetUrl="https://localhost/X509"/>
        <serviceDebug includeExceptionDetailInFaults="true"/>
        <serviceCredentials>
          <clientCertificate>
            <authentication 
              customCertificateValidatorType="WCFValidationServices.X509Validator,WCFValidationServices"
              certificateValidationMode="Custom" />
          </clientCertificate>
          <serviceCertificate 
            findValue="MyServer" 
            storeLocation="CurrentUser" 
            x509FindType="FindBySubjectName"/>
        </serviceCredentials>
      </behavior>
    </serviceBehaviors>
  </behaviors>

  <bindings>
    <netTcpBinding>
      <binding name="x509Binding">
        <security mode="Transport">
          <transport clientCredentialType="Certificate"/>
        </security>
      </binding>
    </netTcpBinding>
  </bindings>

  <services>
    <service behaviorConfiguration="X509Behavior" name="WCFValidationServices.X509Service">
      <endpoint address="" binding="netTcpBinding" bindingConfiguration="x509Binding"
                contract="WCFValidation.IX509" name="X509" />
      <host>
        <baseAddresses>
          <add baseAddress="net.tcp://localhost:8082/X509"/>
        </baseAddresses>
      </host>
    </service>
  </services>
</system.serviceModel>

6. 客戶端組態與呼叫

<system.serviceModel>
  <behaviors>
    <endpointBehaviors>
      <behavior name="ClientBehavior">
        <clientCredentials>
          <clientCertificate storeLocation="CurrentUser" findValue="Client" x509FindType="FindBySubjectName"/>
          <serviceCertificate>
            <authentication certificateValidationMode="None"/> <!-- 信任自簽憑證 -->
          </serviceCertificate>
        </clientCredentials>
      </behavior>
    </endpointBehaviors>
  </behaviors>

  <bindings>
    <netTcpBinding>
      <binding name="X509Binding">
        <security mode="Transport">
          <transport clientCredentialType="Certificate" protectionLevel="EncryptAndSign"/>
        </security>
      </binding>
    </netTcpBinding>
  </bindings>

  <client>
    <endpoint address="net.tcp://localhost:8082/X509"
              binding="netTcpBinding" bindingConfiguration="X509Binding"
              behaviorConfiguration="ClientBehavior"
              contract="IX509" name="X509">
      <identity><dns value="MyServer"/></identity>
    </endpoint>
  </client>
</system.serviceModel>
// 客戶端呼叫代碼
var client = new X509Client("X509");
bool result = client.Test();
client.Close();
Console.WriteLine("驗證結果: " + result); // True
執行成功

常見問題與排查

  • 私鑰存取權限:服務啟動帳戶需有伺服器憑證私鑰讀取權限,可用 FindPrivateKey.exe 定位檔案並授權。
  • 憑證信任鏈:生產環境請使用 CA 簽署憑證,設定 certificateValidationMode="ChainTrust"。
  • 防火牆/連接埠:netTcpBinding 需開放 TCP 8082,確保雙向通訊。

總結

X.509 憑證驗證提供高強度、無狀態的身分認證機制,適合企業級服務整合與跨組織呼叫。雖部署較繁瑣,但透過自動化腳本與集中式憑證管理,可大幅降低維運成本。下一篇將介紹更輕量的 UserName/Password over Message Security 實作。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved