Schannel

A secure channel (Schannel) biztonsági csomag, amelynek hitelesítési szolgáltatásazonosítója RPC_C_AUTHN_GSS_SCHANNEL, a következő nyilvános kulcsú protokollokat támogatja: SSL (Secure Sockets Layer) 2.0 és 3.0 verzió, Transport Layer Security (TLS) 1.0 és Private Communication Technology (PCT) 1.0. A TLS 1.0 az SSL 3.0 szabványosított, kissé módosított verziója, amelyet az Internet Engineering Task Force (IETF) adott ki 1999 januárjában, az RFC 2246 dokumentumban. Mivel a TLS szabványosított, a fejlesztőknek inkább tLS-t kell használniuk, mint SSL-t. A PCT csak a visszamenőleges kompatibilitás érdekében érhető el, és nem használható új fejlesztéshez. Az Schannel biztonsági csomag használata esetén a DCOM automatikusan egyezteti a legjobb protokollt az ügyfél és a kiszolgáló képességeitől függően.

Az alábbi témakörök röviden ismertetik a TLS protokollt és a DCOM használatát.

Megjegyzés:

Az ezekben a szakaszokban található TLS protokollra vonatkozó összes információ az SSL- és PCT-protokollokra is vonatkozik.

 

Mikor érdemes használni a TLS-t?

A TLS az egyetlen biztonsági lehetőség, amely akkor érhető el, ha a kiszolgálóknak igazolniuk kell személyazonosságukat a névtelen ügyfelek számára. Ez különösen fontos az e-kereskedelemben részt venni kívánó webhelyek számára, mivel segít megvédeni a bizalmas információk, például a hitelkártyaszámok továbbítását. A TLS biztosítja, hogy az e-kereskedelmi ügyfelek biztosak lehetnek abban, hogy kivel üzletelnek, mert a kiszolgáló személyazonosságát igazolják. Emellett az e-kereskedelmi kiszolgálónak azt a hatékonyságot is biztosítja, hogy nem kell foglalkoznia az egyes ügyfelek identitásának hitelesítésével.

A TLS megköveteli, hogy minden kiszolgáló igazolja az ügyfelek identitását. Emellett a TLS lehetővé teszi, hogy az ügyfelek igazolják identitásukat a kiszolgálókon. Ez a kölcsönös hitelesítés hasznos lehet bizonyos weblapok hozzáférésének korlátozásához egy nagy vállalati intraneten.

A TLS támogatja a legerősebb hitelesítési szinteket, és olyan nyílt architektúrát kínál, amely lehetővé teszi a titkosítási erő növelését az idő múlásával, hogy lépést tartson a technológiai innovációval. A TLS a legjobb választás olyan környezetekhez, ahol a legmagasabb szintű biztonságra van szükség az átvitt adatokhoz.

A TLS működésének rövid áttekintése

A TLS egy nyilvános kulcsú infrastruktúrára (PKI) épül, amely nyilvános/titkos kulcspárokat használ az adattitkosítás engedélyezéséhez és az adatintegritás kialakításához, és X.509-tanúsítványokat használ a hitelesítéshez.

Számos biztonsági protokoll, például a Kerberos v5 protokoll, egyetlen kulcstól függ az adatok titkosításához és visszafejtéséhez. Az ilyen protokollok ezért a titkosítási kulcsok biztonságos cseréjétől függenek; a Kerberos protokollban ez a Kulcsterjesztési Központtól (KDC) beszerzett jegyeken keresztül történik. Ez megköveteli, hogy a Kerberos protokollt használó összes felhasználó regisztráljon a KDC-ben, ami praktikus korlátozás lenne egy olyan e-kereskedelmi webkiszolgáló esetében, amelynek célja, hogy több millió ügyfelet vonzzon a világ minden tájáról. A TLS ezért egy PKI-re támaszkodik, amely két kulcsot használ az adattitkosításhoz – amikor a pár egyik kulcsa titkosítja az adatokat, csak a pár másik kulcsa tudja visszafejteni azokat. Ennek a kialakításnak az az alapvető előnye, hogy a titkosítás a titkosítási kulcsok biztonságos cseréjének megkövetelése nélkül is elvégezhető.

A PKI egy olyan technikát használ, amelyben az egyik kulcs privát marad, és csak a regisztrált tag számára érhető el, míg a másik kulcs bárki számára nyilvánossá válik a hozzáféréshez. Ha valaki titkos üzenetet szeretne küldeni egy kulcspár tulajdonosának, az üzenet titkosítható a nyilvános kulccsal, és csak a titkos kulcs használható az üzenet visszafejtéséhez.

A kulcspárok az elküldött adatok integritásának ellenőrzésére is szolgálnak. Ehhez a kulcspár tulajdonosa a küldés előtt digitális aláírást csatolhat az adatokhoz. A digitális aláírás létrehozása magában foglalja az adatok kivonatának kiszámítását és a kivonat titkos kulccsal való titkosítását. Mindenki, aki a nyilvános kulcsot használja a digitális aláírás visszafejtéséhez, biztos lehet abban, hogy a digitális aláírásnak csak a titkos kulcs tulajdonosától kell származnia. Emellett a címzett ugyanazzal az algoritmussal kiszámíthatja az adatok kivonatát, mint a feladó, és ha a számított kivonat megegyezik a digitális aláírásban elküldött kivonattal, a címzett biztos lehet abban, hogy az adatok nem lettek módosítva a digitális aláírás után.

A PKI nagy mennyiségű adattitkosításhoz való használatának egyik hátránya a viszonylag lassú teljesítmény. Az intenzív matematika miatt az adatok titkosítása és visszafejtése egy kulcspártól függő aszimmetrikus titkosítással akár 1000-szer lassabb is lehet, mint a titkosítás és a visszafejtés egy szimmetrikus titkosítással, amely csak egyetlen kulcstól függ. A TLS ezért csak a digitális aláírások létrehozására és a munkamenet-specifikus egyetlen kulcs egyeztetésére használ PKI-t, amelyet az ügyfél és a kiszolgáló tömeges adattitkosításhoz és visszafejtéshez fog használni. A TLS az egykulcsos szimmetrikus titkosítások széles választékát támogatja, és a jövőben további titkosítások is hozzáadhatók.

A TLS kézfogási protokollról további információt a TLS kézfogási protokollban talál.

A TLS protokoll mögötti titkosítással kapcsolatos további részletekért lásd: Cryptography Essentials.

X.509-tanúsítványok

A PKI által kezelendő kritikus probléma a használt nyilvános kulcs hitelességének megbízhatósága. Amikor egy olyan vállalatnak kiadott nyilvános kulcsot használ, amellyel üzleti kapcsolatban szeretne lenni, biztosnak kell lennie abban, hogy a kulcs valójában a vállalathoz tartozik, nem pedig egy tolvajhoz, aki meg akarja találni a hitelkártyaszámát.

A kulcspárokat tartalmazó tag identitásának garantálása érdekében a rendszerbiztonsági tag egy X.509-tanúsítványt bocsát ki egy hitelesítésszolgáltató (CA) által. Ez a tanúsítvány olyan információkat tartalmaz, amelyek azonosítják az egyszerű felhasználót, tartalmazzák az ügyfél nyilvános kulcsát, és a hitelesítésszolgáltató digitálisan alá van írva. Ez a digitális aláírás azt jelzi, hogy a hitelesítésszolgáltató úgy véli, hogy a tanúsítványban található nyilvános kulcs valóban a tanúsítvány által azonosított egyszerű kulcshoz tartozik.

És hogyan bízik meg a hitelesítésszolgáltatóban? Mivel maga a hitelesítésszolgáltató rendelkezik egy X.509-tanúsítvánnyal, amelyet egy magasabb szintű hitelesítésszolgáltató írt alá. Ez a tanúsítvány-aláírási lánc addig folytatódik, amíg el nem éri a legfelső szintű hitelesítésszolgáltatót, amely a saját tanúsítványait aláíró hitelesítésszolgáltató. Ha megbízik egy tanúsítvány legfelső szintű hitelesítésszolgáltatójának integritásában, akkor magának a tanúsítványnak a hitelességében kell megbíznia. Ezért a rendszergazda számára fontos feladat a megbízható legfelső szintű hitelesítésszolgáltatók kiválasztása.

Ügyféltanúsítványok

Amikor először jelentek meg a biztonsági átviteli réteg protokolljai, elsődleges céljuk az volt, hogy garantálják, hogy az ügyfél egy hiteles kiszolgálóhoz csatlakozik, és segítsen megvédeni az adatok adatvédettségét átvitel közben. Az SSL 3.0 és a TLS 1.0 azonban támogatja az ügyfél tanúsítványának továbbítását a protokoll kézfogása során. Ez az opcionális funkció lehetővé teszi az ügyfél és a kiszolgáló kölcsönös hitelesítését.

Az ügyféltanúsítvány használatáról az alkalmazás kontextusában kell dönteni. Az ügyféltanúsítványok szükségtelenek, ha az elsődleges követelmény a kiszolgáló hitelesítése. Ha azonban az ügyfélhitelesítés elengedhetetlen, az ügyfél tanúsítványa használható az alkalmazáson belüli egyéni hitelesítés helyett. Az ügyféltanúsítványok használata előnyösebb az egyéni hitelesítésnél, mivel a felhasználók számára egyetlen bejelentkezési forgatókönyvet biztosít.

TLS használata a COM-ban

A TLS csak a megszemélyesítés megszemélyesítési (RPC_C_IMP_LEVEL_IMPERSONATE) szintjét támogatja. Ha a COM egy proxy hitelesítési szolgáltatásaként tárgyalja a TLS-t, a COM a megszemélyesítési szintet a folyamat alapértelmezett értékétől függetlenül megszemélyesítésre állítja. Ahhoz, hogy a megszemélyesítés megfelelően működjön a TLS-ben, az ügyfélnek X.509-tanúsítványt kell biztosítania a kiszolgálónak, és a kiszolgálónak a kiszolgálón egy adott felhasználói fiókhoz kell hozzárendelnie a tanúsítványt. További információkért tekintse meg a tanúsítványok felhasználói fiókokhoz való hozzárendelésének részletes útmutatóját.

A TLS nem támogatja az álcázást. Ha a CoInitializeSecurity vagy egy IClientSecurity::SetBlanket hívásban van megadva álcázási jelző és TLS, a rendszer E_INVALIDARG ad vissza.

A TLS nem működik a Nincs hitelesítési szinttel. Az ügyfél és a kiszolgáló közötti kézfogás megvizsgálja az egyes felhasználók által beállított hitelesítési szintet, és kiválasztja a kapcsolat magasabb biztonsági beállításait.

A TLS biztonsági paraméterei a CoInitializeSecurity és a CoSetProxyBlanket meghívásával állíthatók be. A következő szakaszok ismertetik a hívások indításának árnyalatait.

Hogyan állítja be a kiszolgáló a biztonsági takarót?

Ha egy kiszolgáló TLS-t szeretne használni, meg kell adnia a Schannelt (RPC_C_AUTHN_GSS_SCHANNEL) hitelesítési szolgáltatásként a CoInitializeSecurityasAuthSvc paraméterében. Ha meg szeretné akadályozni, hogy az ügyfelek kevésbé biztonságos hitelesítési szolgáltatással csatlakozzanak a kiszolgálóhoz, a kiszolgálónak csak a Schannelt kell hitelesítési szolgáltatásként megadnia, amikor meghívja a CoInitializeSecurity szolgáltatást. A kiszolgáló a CoInitializeSecurity nevet követően nem tudja módosítani a biztonsági takarót.

A TLS használatához a következő paramétereket kell megadni, amikor egy kiszolgáló meghívja a CoInitializeSecurityet:

  • A pVoidnak egy IAccessControl-objektumra mutató vagy egy SECURITY_DESCRIPTOR mutatónak kell lennie. Nem lehet NULL vagy mutató egy AppID-hez.
  • a cAuthSvc nem lehet 0 vagy -1. A COM-kiszolgálók soha nem választják a Schannelt, ha a cAuthSvcértéke -1.
  • Az asAuthSvc-nek lehetséges hitelesítési szolgáltatásként meg kell adnia az Schannelt. Ez a SOLE_AUTHENTICATION_LIST Schannel-tagjára vonatkozó alábbi SOLE_AUTHENTICATION_SERVICE paraméterek beállításával történik:
    • A dwAuthnSvc-nek RPC_C_AUTHN_GSS_SCHANNEL kell lennie.
    • A dwAuthzSvc-nek RPC_C_AUTHZ_NONE kell lennie. Jelenleg a rendszer figyelmen kívül hagyja.
    • A pPrincipalName-nek egy CERT_CONTEXT mutatójának kell lennie, amely a kiszolgáló X.509-tanúsítványát képviselő OLECHAR-ra mutat.
  • A dwAuthnLevel azt a minimális hitelesítési szintet jelzi, amelyet az ügyfelek elfogadnak a sikeres kapcsolat érdekében. Nem lehet RPC_C_AUTHN_LEVEL_NONE.
  • A dwCapabilities nem rendelkezhet a EOAC_APPID jelzőkészlettel. A EOAC_ACCESS_CONTROL jelzőt akkor kell beállítani, ha a pVoid egy IAccessControl-objektumra mutat; nem szabad beállítani, ha a pVoid egy SECURITY_DESCRIPTOR mutat. Az esetlegesen beállított egyéb jelzőkért lásd a CoInitializeSecurity című témakört.

A CoInitializeSecurity használatával kapcsolatos további információkért lásd: Processwide Security beállítása a CoInitializeSecurity használatával.

Hogyan állítja be az ügyfél a biztonsági takarót?

Ha egy ügyfél TLS-t szeretne használni, meg kell adnia a Schannelt (RPC_C_AUTHN_GSS_SCHANNEL) a hitelesítési szolgáltatások listájában a CoInitializeSecuritypAuthList paraméterében. Ha a Schannel nincs megadva lehetséges hitelesítési szolgáltatásként a CoInitializeSecurity meghívásakor, a CoSetProxyBlanket (vagy IClientSecurity::SetBlanket) egy későbbi hívása meghiúsul, ha megkísérli megadni a Schannelt hitelesítési szolgáltatásként.

A következő paramétereket kell megadni, amikor egy ügyfél meghívja a CoInitializeSecurityet:

  • A dwAuthnLevel az ügyfél által használni kívánt alapértelmezett hitelesítési szintet adja meg. Nem lehet RPC_C_AUTHN_LEVEL_NONE.
  • A dwImpLevelnek RPC_C_IMP_LEVEL_IMPERSONATE kell lennie.
  • A pAuthListnek a következő SOLE_AUTHENTICATION_INFO paraméterekkel kell rendelkeznie a lista tagjaként:
    • A dwAuthnSvc-nek RPC_C_AUTHN_GSS_SCHANNEL kell lennie.
    • A dwAuthzSvc-nek RPC_C_AUTHZ_NONE kell lennie.
    • A pAuthInfo egy CERT_CONTEXT mutatója, amely az ügyfél X.509-tanúsítványát jelöli. Ha az ügyfél nem rendelkezik tanúsítvánnyal, vagy nem szeretné bemutatni a tanúsítványát a kiszolgálónak, a pAuthInfo-nakNULL értékűnek kell lennie, és névtelen kapcsolatot kell létesíteni a kiszolgálóval.
  • A dwCapabilities olyan jelzők készlete, amelyek további ügyfélképességeket jeleznek. A jelölők beállításáról a CoInitializeSecurity című témakörben olvashat.

A CoInitializeSecurity használatával kapcsolatos további információkért lásd: Processwide Security beállítása a CoInitializeSecurity használatával.

Hogyan módosítja az ügyfél a biztonsági takarót?

Ha egy ügyfél TLS-t szeretne használni, de a CoInitializeSecurity hívása után módosítani szeretné a biztonsági takarót, a CoSetProxyBlanket vagy az IClientSecurity::SetBlanket metódust a CoInitializeSecurity hívásához hasonló paraméterekkel kell meghívnia, az alábbi különbségekkel:

  • A pServerPrincName a kiszolgáló egyszerű nevét jelzi msstd vagy fullsic formátumban. Ezekről a formátumokról további információt az Egyszerű nevek című témakörben talál. Ha az ügyfél rendelkezik a kiszolgáló X.509-tanúsítványával, az RpcCertGeneratePrincipalName meghívásával megtalálhatja az egyszerű nevet.
  • A pAuthInfo egy CERT_CONTEXT mutatója, amely a RPC_AUTH_IDENTITY_HANDLE mutatója, amely az ügyfél X.509-tanúsítványát jelöli. Ha az ügyfél nem rendelkezik tanúsítvánnyal, vagy nem szeretné bemutatni a tanúsítványát a kiszolgálónak, a pAuthInfo-nakNULL értékűnek kell lennie, és névtelen kapcsolatot kell létesíteni a kiszolgálóval.
  • A dwCapabilities olyan jelzőkből áll, amelyek további ügyfélképességeket jeleznek. A biztonsági keret beállításainak módosításához csak négy jelző használható: EOAC_DEFAULT, EOAC_MUTUAL_AUTH, EOAC_ANY_AUTHORITY (ez a jelző elavult) és EOAC_MAKE_FULLSIC. További információ: CoSetProxyBlanket.

További információ a CoSetProxyBlanket használatáról: A biztonság beállítása az interfészproxy szintjén.

Példa: Az ügyfél módosítja a biztonsági takarót

Az alábbi példa bemutatja, hogyan módosíthatja az ügyfél a biztonsági takarót úgy, hogy az megfeleljen a kiszolgáló X.509-tanúsítványának megadására vonatkozó kérésnek. A hibakezelési kód kihagyva a rövidség kedvéért.

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- és biztonsági csomagok