Шифрование / дешифрование WCF с использованием сертификатов сервера и клиента - PullRequest
0 голосов
/ 08 января 2020

Я создал службу, в которой на сервере, где я размещаю службу, будет частный сертификат, и у клиента будет его ключ c. И у клиента будет другой закрытый ключ, где он будет зашифровывать сообщение, которое он отправляет в конечную точку, которую я создаю, и у меня есть ключ publi c, который я буду использовать для расшифровки сообщения. То, что у меня есть в конфигурационном файле сервера.

Так что этот позаботится о главном частном сертификате, где будет размещаться сервис. Я не уверен, куда / как поместить ключ publi c сертификата, где клиент использует / использует закрытый ключ для шифрования сообщения.

Любая помощь будет очень признательна.

<?xml version="1.0"?>
<configuration>
  <appSettings>
  </appSettings>
  <system.web>
    <httpRuntime maxRequestLength="2147483647"/>
    <compilation debug="false" strict="false" explicit="true" targetFramework="4.5.2"/>
    <pages controlRenderingCompatibilityVersion="4.0"/>
    <customErrors mode="Off"/>
  </system.web>
  <system.serviceModel>
    <bindings>
      <basicHttpBinding>
        <binding name="basicHttpEndPointBinding">
          <security mode="Message">
            <message clientCredentialType="Certificate"/>
          </security>
        </binding>
      </basicHttpBinding>
    </bindings>
    <services>
      <service behaviorConfiguration="wcfJNet.ServiceBehavior" name="wcfJNetService">
        <endpoint address="" binding="basicHttpBinding" 
          bindingConfiguration="basicHttpEndPointBinding"
          contract="IJNetService">
          <identity>
            <dns value="xxxxxx" />
          </identity>
        </endpoint>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="wcfJNet.ServiceBehavior">
          <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
          <serviceDebug includeExceptionDetailInFaults="true"/>
          <serviceCredentials>
            <serviceCertificate findValue="0000xx000" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySerialNumber"/>
            <clientCertificate>
              <authentication certificateValidationMode="PeerOrChainTrust"/>
            </clientCertificate>
          </serviceCredentials>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <protocolMapping>
      <add binding="basicHttpsBinding" scheme="https"/>
    </protocolMapping>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
  </system.serviceModel>
  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
    <!--
        To browse web app root directory during debugging, set the value below to true.
        Set to false before deployment to avoid disclosing web app folder information.
      -->
    <directoryBrowse enabled="true"/>
  </system.webServer>
</configuration>

1 Ответ

1 голос
/ 08 января 2020

Очень хорошо, у вас есть глубокое понимание механизма работы SSL-сертификата. См. Ссылку ниже.
https://docs.microsoft.com/en-us/dotnet/framework/wcf/feature-details/message-security-with-a-certificate-client
Клиентская и серверная стороны автоматически согласовывают ключ сертификатов publi c во время связи для шифрования сообщения с другими ключ publi c и дешифрование сообщения soap с помощью закрытого ключа. Таким образом, нам не нужно вручную программировать эту процедуру. Достаточно установить сертификат друг друга в локальном хранилище сертификатов.
Если мы аутентифицируем клиента в режиме безопасности сообщений, нам необходимо использовать раздел service credential для настройки сертификата службы. Как и то, что вы сделали.

<serviceCredentials>
            <serviceCertificate findValue="0000xx000" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySerialNumber"/>
            <clientCertificate>
              <authentication certificateValidationMode="PeerOrChainTrust"/>
            </clientCertificate>
          </serviceCredentials>

На стороне клиента, как правило, нам нужно указать два сертификата, один - сертификат службы, другой - сертификат клиента.

//message security, we need to specify both the default certificate and the client certificate.
            ServiceReference1.ServiceClient client = new ServiceReference1.ServiceClient();            client.ClientCredentials.ServiceCertificate.SetDefaultCertificate(StoreLocation.LocalMachine, StoreName.Root, X509FindType.FindByThumbprint, "cbc81f77ed01a9784a12483030ccd497f01be71c");
client.ClientCredentials.ClientCertificate.SetCertificate(StoreLocation.LocalMachine, StoreName.My, X509FindType.FindByThumbprint, "9b8db0dfe615458ace0ae9e89fcb983c5d16f633");
            try
            {
                var result = client.SayHello();
                Console.WriteLine(result);
            }
            catch (Exception)
            {
                throw;
            }

Что касается доверительных отношений между сертификатами, на стороне клиента нам нужно установить сертификат сервера в LocalCA, а на стороне сервера нам нужно установить клиент сертификат в определенном месте в зависимости от режима аутентификации. По умолчанию его можно установить в LocalCA.

    //this is default authentication mode. 
  sh.Credentials.ClientCertificate.Authentication.CertificateValidationMode= System.ServiceModel.Security.X509CertificateValidationMode.ChainTrust;

Не стесняйтесь, дайте мне знать, если я могу чем-то помочь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...