Delen via


Schannel

Het beveiligingspakket Secure Channel (Schannel), waarvan de verificatieservice-id is RPC_C_AUTHN_GSS_SCHANNEL, ondersteunt de volgende protocollen op basis van openbare sleutels: SSL (Secure Sockets Layer) versie 2.0 en 3.0, Transport Layer Security (TLS) 1.0 en PCT (Private Communication Technology) 1.0. TLS 1.0 is een gestandaardiseerde, enigszins gewijzigde versie van SSL 3.0 die in januari 1999 is uitgegeven door de Internet Engineering Task Force (IETF) in document RFC 2246. Omdat TLS is gestandaardiseerd, worden ontwikkelaars aangemoedigd OM TLS te gebruiken in plaats van SSL. PCT is alleen opgenomen voor achterwaartse compatibiliteit en mag niet worden gebruikt voor nieuwe ontwikkeling. Wanneer het Schannel-beveiligingspakket wordt gebruikt, onderhandelt DCOM automatisch over het beste protocol, afhankelijk van de mogelijkheden van de client en de server.

In de volgende onderwerpen wordt kort het TLS-protocol beschreven en hoe het werkt met DCOM.

Notitie

Alle informatie over het TLS-protocol in deze secties is ook van toepassing op de SSL- en PCT-protocollen.

 

Wanneer gebruikt u TLS?

TLS is de enige beveiligingsoptie die beschikbaar is wanneer servers hun identiteit moeten bewijzen aan anonieme clients. Dit is met name belangrijk voor websites die willen deelnemen aan e-commerce, omdat het helpt bij het beschermen van de overdracht van gevoelige informatie, zoals creditcardnummers. TLS zorgt ervoor dat de e-commerceklanten zeker kunnen zijn van wie ze zaken doen omdat ze een bewijs van de identiteit van de server krijgen. Het geeft de e-commerceserver ook de efficiëntie om zich niet bezig te houden met het verifiëren van de identiteit van elk van zijn klanten.

TLS vereist dat alle servers hun identiteit bewijzen aan clients. Daarnaast biedt TLS de mogelijkheid om clients hun identiteit aan servers te laten bewijzen. Deze wederzijdse verificatie kan nuttig zijn bij het beperken van de toegang van bepaalde webpagina's in een groot bedrijfsintranet.

TLS ondersteunt de sterkste verificatieniveaus en biedt een open architectuur waarmee versleutelingssterkte in de loop van de tijd kan toenemen om technologische innovatie bij te houden. TLS is de beste keuze voor omgevingen waarbij het hoogste beveiligingsniveau gewenst is voor de gegevens die worden verzonden.

Kort overzicht van hoe TLS werkt

TLS is gebaseerd op een openbare-sleutelinfrastructuur (PKI), die gebruikmaakt van openbare/persoonlijke sleutelparen voor het inschakelen van gegevensversleuteling en het tot stand brengen van gegevensintegriteit en X.509-certificaten voor verificatie.

Veel beveiligingsprotocollen, zoals het Kerberos v5-protocol, zijn afhankelijk van één sleutel voor het versleutelen en ontsleutelen van gegevens. Dergelijke protocollen zijn dus afhankelijk van de veilige uitwisseling van versleutelingssleutels; in het Kerberos-protocol wordt dit gedaan via tickets die zijn verkregen via het Key Distribution Center (KDC). Dit vereist dat iedereen die het Kerberos-protocol gebruikt, wordt geregistreerd bij de KDC, wat een onpraktische beperking zou zijn voor een e-commercewebserver die bedoeld is om miljoenen klanten uit de hele wereld aan te trekken. TLS is daarom afhankelijk van een PKI, die twee sleutels gebruikt voor gegevensversleuteling'', wanneer één sleutel van het paar de gegevens versleutelt, kan alleen de andere sleutel van het paar deze ontsleutelen. Het belangrijkste voordeel van dit ontwerp is dat versleuteling kan worden uitgevoerd zonder dat de veilige uitwisseling van versleutelingssleutels is vereist.

Een PKI maakt gebruik van een techniek waarbij een van de sleutels privé wordt gehouden en alleen beschikbaar is voor de principal aan wie deze is geregistreerd, terwijl de andere sleutel openbaar wordt gemaakt voor iedereen die toegang heeft. Als iemand een privébericht wil verzenden naar de eigenaar van een sleutelpaar, kan het bericht worden versleuteld met de openbare sleutel en kan alleen de persoonlijke sleutel worden gebruikt om het bericht te ontsleutelen.

Sleutelparen worden ook gebruikt om de integriteit van de verzonden gegevens te controleren. Hiervoor kan de eigenaar van het sleutelpaar een digitale handtekening toevoegen aan de gegevens voordat deze worden verzonden. Het maken van een digitale handtekening omvat het berekenen van een hash van de gegevens en het versleutelen van de hash met de persoonlijke sleutel. Iedereen die de openbare sleutel gebruikt om de digitale handtekening te ontsleutelen, is ervan verzekerd dat de digitale handtekening alleen afkomstig is van de persoon die eigenaar is van de persoonlijke sleutel. Bovendien kan de ontvanger een hash van de gegevens berekenen met hetzelfde algoritme als de afzender en als de berekende hash overeenkomt met de hash die in de digitale handtekening is verzonden, kan de ontvanger er zeker van zijn dat de gegevens niet zijn gewijzigd nadat ze digitaal zijn ondertekend.

Een nadeel van het gebruik van een PKI voor gegevensversleuteling met een hoog volume is de relatief trage prestaties. Vanwege de intensieve wiskunde kan versleuteling en ontsleuteling van gegevens met behulp van een asymmetrische codering die afhankelijk is van een sleutelpaar maximaal 1000 keer langzamer zijn dan versleuteling en ontsleuteling met behulp van een symmetrische codering die slechts afhankelijk is van één sleutel. TLS gebruikt daarom alleen een PKI voor het genereren van digitale handtekeningen en voor het onderhandelen over de sessiespecifieke enkele sleutel die wordt gebruikt door zowel de client als de server voor bulkgegevensversleuteling en ontsleuteling. TLS ondersteunt een groot aantal symmetrische coderingen met één sleutel en er kunnen in de toekomst extra coderingen worden toegevoegd.

Zie TLS Handshake Protocolvoor meer informatie over het TLS-handshakeprotocol.

Zie Cryptography Essentialsvoor meer informatie over de cryptografie achter het TLS-protocol.

X.509-certificaten

Een kritiek probleem dat moet worden afgehandeld door een PKI is de mogelijkheid om de echtheid van de openbare sleutel te vertrouwen die wordt gebruikt. Wanneer u een openbare sleutel gebruikt die is uitgegeven aan een bedrijf waarmee u zaken wilt doen, wilt u er zeker van zijn dat de sleutel daadwerkelijk deel uitmaakt van het bedrijf in plaats van een dief die uw creditcardnummer wil ontdekken.

Om de identiteit van een principal met een sleutelpaar te garanderen, krijgt de principal een X.509-certificaat uitgegeven door een certificeringsinstantie (CA). Dit certificaat bevat informatie die de principal identificeert, de openbare sleutel van de principal bevat en digitaal wordt ondertekend door de CA. Deze digitale handtekening geeft aan dat de CA van mening is dat de openbare sleutel in het certificaat echt deel uitmaakt van de principal die door het certificaat is geïdentificeerd.

En hoe vertrouwt u de CA? Omdat de CA zelf een X.509-certificaat bevat dat is ondertekend door een ca op een hoger niveau. Deze keten van certificaathandtekeningen wordt voortgezet totdat deze een basis-CA bereikt. Dit is een CA die zijn eigen certificaten ondertekent. Als u de integriteit van de basis-CA van een certificaat vertrouwt, moet u de echtheid van het certificaat zelf kunnen vertrouwen. Daarom is het kiezen van basis-CA's die u bereid bent te vertrouwen een belangrijke plicht voor een systeembeheerder.

Clientcertificaten

Toen de beveiligingsprotocollen voor transportlaag voor het eerst opkwamen, was hun primaire doel om te garanderen dat een client verbinding maakte met een authentieke server en de privacy van gegevens tijdens de overdracht beschermt. SSL 3.0 en TLS 1.0 bevatten echter ook ondersteuning voor de overdracht van het certificaat van een client tijdens de handshake van het protocol. Deze optionele functie maakt wederzijdse verificatie van de client en server mogelijk.

De beslissing of een clientcertificaat moet worden gebruikt in de context van de toepassing. Clientcertificaten zijn niet nodig als de primaire vereiste de server authenticeert. Als clientverificatie echter essentieel is, kan het certificaat van een client worden gebruikt in plaats van te vertrouwen op aangepaste verificatie in de toepassing. Het gebruik van clientcertificaten verdient de voorkeur boven aangepaste verificatie, omdat het gebruikers een scenario voor eenmalige aanmelding biedt.

TLS gebruiken in COM

TLS ondersteunt alleen het imitatieniveau (RPC_C_IMP_LEVEL_IMPERSONATE). Als COM onderhandelt over TLS als verificatieservice op een proxy, stelt COM het imitatieniveau in op imitatie, ongeacht de standaardinstelling van het proces. Voor een goede werking van imitatie in TLS moet de client een X.509-certificaat aan de server opgeven en moet het certificaat op de server zijn toegewezen aan een bepaald gebruikersaccount op de server. Zie de stapsgewijze handleiding voor het toewijzen van certificaten aan gebruikersaccountsvoor meer informatie.

TLS biedt geen ondersteuning voor cloaking. Als een cloakingvlag en TLS zijn opgegeven in een CoInitializeSecurity of een IClientSecurity::SetBlanket aanroep, wordt E_INVALIDARG geretourneerd.

TLS werkt niet met het verificatieniveau ingesteld op Geen. De handshake tussen de client en de server onderzoekt het verificatieniveau dat door elk is ingesteld en kiest de hogere beveiligingsinstelling voor de verbinding.

De beveiligingsparameters voor TLS kunnen worden ingesteld door CoInitializeSecurity en CoSetProxyBlanketaan te roepen. In de volgende secties worden de nuances beschreven die betrokken zijn bij het maken van deze oproepen.

Hoe een server de beveiligingsdeken instelt

Als een server TLS wil gebruiken, moet deze Schannel (RPC_C_AUTHN_GSS_SCHANNEL) opgeven als verificatieservice in de parameter asAuthSvc parameter van CoInitializeSecurity. Om te voorkomen dat clients verbinding maken met de server met behulp van een minder veilige verificatieservice, moet de server alleen Schannel opgeven als een verificatieservice wanneer deze CoInitializeSecurityaanroept. De server kan de beveiligingsdeken niet wijzigen nadat deze CoInitializeSecurityheeft aangeroepen.

Als u TLS wilt gebruiken, moeten de volgende parameters worden opgegeven wanneer een server CoInitializeSecurityaanroept:

  • pVoid- moet een aanwijzer zijn naar een IAccessControl-object of een aanwijzer naar een SECURITY_DESCRIPTOR. Het mag niet worden NULL- of een aanwijzer naar een AppID.
  • cAuthSvc- mag niet 0 of -1 zijn. COM-servers kiezen nooit Schannel wanneer cAuthSvc--1 is.
  • asAuthSvc- moet Schannel opgeven als een mogelijke verificatieservice. Dit wordt gedaan door de volgende SOLE_AUTHENTICATION_SERVICE parameters in te stellen voor het Schannel-lid van de SOLE_AUTHENTICATION_LIST:
    • dwAuthnSvc- moet zijn RPC_C_AUTHN_GSS_SCHANNEL.
    • dwAuthzSvc- moet worden RPC_C_AUTHZ_NONE. Op dit moment wordt dit genegeerd.
    • pPrincipalName- moet een aanwijzer zijn naar een CERT_CONTEXT, casten als een aanwijzer naar OLECHAR, die het X.509-certificaat van de server vertegenwoordigt.
  • dwAuthnLevel geeft het minimale verificatieniveau aan dat wordt geaccepteerd door clients voor een geslaagde verbinding. Het kan niet RPC_C_AUTHN_LEVEL_NONE.
  • dwCapabilities mag niet de EOAC_APPID vlag hebben ingesteld. De EOAC_ACCESS_CONTROL vlag moet worden ingesteld als pVoid- verwijst naar een IAccessControl--object; deze moet niet worden ingesteld als pVoid- verwijst naar een SECURITY_DESCRIPTOR. Zie CoInitializeSecurityvoor andere vlaggen die kunnen worden ingesteld.

Zie Procesomvattende beveiliging instellen met CoInitializeSecurityvoor meer informatie over het gebruik van CoInitializeSecurity.

Hoe een client de beveiligingsdeken instelt

Als een client TLS wil gebruiken, moet deze Schannel (RPC_C_AUTHN_GSS_SCHANNEL) opgeven in de lijst met verificatieservices in de parameter pAuthList parameter van CoInitializeSecurity. Als Schannel niet is opgegeven als een mogelijke verificatieservice wanneer CoInitializeSecurity wordt aangeroepen, mislukt een latere aanroep naar CoSetProxyBlanket (of IClientSecurity::SetBlanket) als er wordt geprobeerd om Schannel op te geven als de verificatieservice.

De volgende parameters moeten worden opgegeven wanneer een client CoInitializeSecurityaanroept:

  • dwAuthnLevel geeft het standaardverificatieniveau op dat de client wil gebruiken. Het kan niet RPC_C_AUTHN_LEVEL_NONE.
  • dwImpLevel- moet RPC_C_IMP_LEVEL_IMPERSONATE zijn.
  • pAuthList- moet de volgende SOLE_AUTHENTICATION_INFO parameters hebben als lid van de lijst:
    • dwAuthnSvc- moet zijn RPC_C_AUTHN_GSS_SCHANNEL.
    • dwAuthzSvc- moet zijn RPC_C_AUTHZ_NONE.
    • pAuthInfo- is een aanwijzer naar een CERT_CONTEXT, cast als een aanwijzer naar ongeldigheid, die het X.509-certificaat van de client vertegenwoordigt. Als de client geen certificaat heeft of het certificaat niet aan de server wil presenteren, moet pAuthInfo-NULL- zijn en wordt er een anonieme verbinding met de server geprobeerd.
  • dwCapabilities is een set vlaggen die extra clientmogelijkheden aangeven. Zie CoInitializeSecurity voor informatie over welke vlaggen moeten worden ingesteld.

Zie Procesomvattende beveiliging instellen met CoInitializeSecurityvoor meer informatie over het gebruik van CoInitializeSecurity.

Hoe een klant de beveiligingsdeken wijzigt

Als een client TLS wil gebruiken maar de beveiligingsdeken wil wijzigen nadat CoInitializeSecurity-is aangeroepen, moet deze CoSetProxyBlanket- of IClientSecurity:SetBlanket- aanroepen met parameters die vergelijkbaar zijn met de parameters die in de aanroep naar CoInitializeSecurityworden gebruikt, met de volgende verschillen:

  • pServerPrincName geeft de principal-naam van de server aan, in msstd- of fullsic-indeling. Zie Principal Namesvoor meer informatie over deze indelingen. Als de client het X.509-certificaat van de server heeft, kan deze de principal-naam vinden door RpcCertGeneratePrincipalNameaan te roepen.
  • pAuthInfo- is een aanwijzer naar een CERT_CONTEXT, cast als een aanwijzer naar RPC_AUTH_IDENTITY_HANDLE, die het X.509-certificaat van de client vertegenwoordigt. Als de client geen certificaat heeft of het certificaat niet aan de server wil presenteren, moet pAuthInfo-NULL- zijn en wordt er een anonieme verbinding met de server geprobeerd.
  • dwCapabilities bestaat uit vlaggen die extra clientmogelijkheden aangeven. Er kunnen slechts vier vlaggen worden gebruikt om de instellingen voor beveiligingsdeken te wijzigen: EOAC_DEFAULT, EOAC_MUTUAL_AUTH, EOAC_ANY_AUTHORITY (deze vlag is afgeschaft) en EOAC_MAKE_FULLSIC. Zie CoSetProxyBlanketvoor meer informatie.

Zie Instellingsbeveiliging op interfaceproxyproxyniveauvoor meer informatie over het gebruik van CoSetProxyBlanket.

Voorbeeld: Client wijzigt de beveiligingsdeken

In het volgende voorbeeld ziet u hoe een client de beveiligingsdeken kan wijzigen om tegemoet te komen aan een aanvraag van de server voor de client om het X.509-certificaat op te geven. Code voor foutafhandeling wordt weggelaten voor beknoptheid.

void ClientChangesSecurity ()
{
  HCRYPTPROV                   provider           = 0;
  HCERTSTORE                   cert_store         = NULL;
  PCCERT_CONTEXT               client_cert        = NULL;
  PCCERT_CONTEXT               server_cert        = NULL;
  WCHAR                        *server_princ_name = NULL;
  ISecret                      *pSecret           = NULL;
  MULTI_QI                     server_instance;
  COSERVERINFO                 server_machine;
  SOLE_AUTHENTICATION_LIST     auth_list;
  SOLE_AUTHENTICATION_INFO     auth_info[1];



  // Specify all the authentication info. 
  // The client is willing to connect using SChannel,
  //   with no client certificate.
  auth_list.cAuthInfo     = 1;
  auth_list.aAuthInfo     = auth_info;
  auth_info[0].dwAuthnSvc = RPC_C_AUTHN_GSS_SCHANNEL;
  auth_info[0].dwAuthzSvc = RPC_C_AUTHZ_NONE;
  auth_info[0].pAuthInfo  = NULL;  // No certificate

  // Initialize client security with no client certificate.
  CoInitializeSecurity( NULL, -1, NULL, NULL,
                        RPC_C_AUTHN_LEVEL_PKT,
                        RPC_C_IMP_LEVEL_IMPERSONATE, &auth_list,
                        EOAC_NONE, NULL );
  
  // Specify info for the proxy.
  server_instance = {&IID_ISecret, NULL, S_OK};
  server_machine  = {0, L"ServerMachineName", NULL, 0};
  
  // Create a proxy.
  CoCreateInstanceEx( CLSID_Secret, NULL, CLSCTX_REMOTE_SERVER, 
                      &server_machine, 1, &server_instance);
  pSecret = (ISecret *) server_instance.pItf;

  //** The client obtained the server's certificate during the handshake.
  //** The server requests a certificate from the client.

  // Get the default certificate provider.
  CryptAcquireContext( &provider, NULL, NULL, PROV_RSA_SCHANNEL, 0 );

  // Open the certificate store.
  cert_store = CertOpenSystemStore( provider, L"my" );

  // Find the client's certificate.
  client_cert = 
    CertFindCertificateInStore( cert_store,
                                X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
                                0,
                                CERT_FIND_SUBJECT_STR,
                                L"ClientName",  // Use the principal name
                                NULL );

  // Find the fullsic principal name of the server.
  RpcCertGeneratePrincipalName( server_cert, RPC_C_FULL_CERT_CHAIN, 
                                &server_princ_name );

  // Change the client's security: 
  // Increase the authentication level and attach a certificate.
  CoSetProxyBlanket( pSecret, RPC_C_AUTHN_GSS_SCHANNEL,
                     RPC_C_AUTHZ_NONE,
                     server_princ_name, RPC_C_AUTHN_LEVEL_PKT_PRIVACY,
                     RPC_C_IMP_LEVEL_IMPERSONATE, 
                     (RPC_AUTH_IDENTITY_HANDLE *) client_cert,
                     EOAC_NONE );

  cleanup:
  if (server_princ_name != NULL)
    RpcStringFree( &server_princ_name );
  if (client_cert != NULL)
    CertFreeCertificateContext(client_cert);
  if (server_cert != NULL)
    CertFreeCertificateContext(server_cert);
  if (cert_store != NULL)
    CertCloseStore( cert_store, CERT_CLOSE_STORE_CHECK_FLAG );
  if (provider != 0 )
    CryptReleaseContext( provider, 0 );
  if (pSecret != NULL)
    pSecret->Release();
  CoUninitialize();
}

COM- en beveiligingspakketten