Schannel
Le package de sécurité Schannel (Secure Channel), dont l’identificateur de service d’authentification est RPC_C_AUTHN_GSS_SCHANNEL, prend en charge les protocoles basés sur des clés publiques suivants : SSL (Secure Sockets Layer) versions 2.0 et 3.0, TLS (Transport Layer Security) 1.0 et Private Communication Technology (PCT) 1.0. TLS 1.0 est une version standardisée et légèrement modifiée de SSL 3.0 émise par le Groupe de travail d’ingénierie Internet (IETF) en janvier 1999, dans le document RFC 2246. Étant donné que TLS a été normalisé, les développeurs sont encouragés à utiliser TLS plutôt que SSL. LE PCT est inclus uniquement pour la compatibilité descendante et ne doit pas être utilisé pour le nouveau développement. Lorsque le package de sécurité Schannel est utilisé, DCOM négocie automatiquement le meilleur protocole, en fonction des fonctionnalités client et serveur.
Les rubriques suivantes décrivent brièvement le protocole TLS et son fonctionnement avec DCOM.
- Quand utiliser tls
- vue d’ensemble de brève vue d’ensemble du fonctionnement de TLS
- certificats X.509
-
utiliser TLS dans com
- comment un serveur définit le de couverture de sécurité
- comment un client définit le de couverture de sécurité
- comment un client modifie le de couverture de sécurité
- exemple : le client modifie le couverture de sécurité
- rubriques connexes
Note
Toutes les informations sur le protocole TLS dans ces sections s’appliquent également aux protocoles SSL et PCT.
Quand utiliser TLS
TLS est la seule option de sécurité disponible lorsque les serveurs doivent prouver leur identité aux clients anonymes. Cela est particulièrement important pour les sites web qui souhaitent participer au commerce électronique, car il permet de protéger la transmission d’informations sensibles telles que les numéros de carte de crédit. TLS garantit que les clients e-commerce peuvent être certains d’entre eux qui font des affaires, car ils reçoivent la preuve de l’identité du serveur. Il donne également au serveur de commerce électronique l’efficacité de ne pas avoir à se soucier de l’authentification de l’identité de chacun de ses clients.
TLS exige que tous les serveurs prouvent leur identité auprès des clients. De plus, TLS offre la possibilité d’avoir des clients qui prouvent leur identité aux serveurs. Cette authentification mutuelle peut être utile pour restreindre l’accès de certaines pages web dans un intranet d’entreprise volumineux.
TLS prend en charge les niveaux d’authentification les plus forts et offre une architecture ouverte qui permet à la puissance du chiffrement d’augmenter au fil du temps pour suivre l’innovation technologique. TLS est le meilleur choix pour les environnements où le niveau de sécurité le plus élevé est souhaité pour les données en transit.
Brève vue d’ensemble du fonctionnement de TLS
TLS repose sur une infrastructure à clé publique (PKI), qui utilise des paires de clés publiques/privées pour activer le chiffrement des données et établir l’intégrité des données et utilise des certificats X.509 pour l’authentification.
De nombreux protocoles de sécurité, tels que le protocole Kerberos v5, dépendent d’une clé unique pour chiffrer et déchiffrer des données. Ces protocoles dépendent donc de l’échange sécurisé de clés de chiffrement ; dans le protocole Kerberos, cela s’effectue via des tickets obtenus à partir du Centre de distribution de clés (KDC). Cela exige que tout le monde qui utilise le protocole Kerberos soit inscrit auprès du KDC, ce qui serait une limitation irréalisable pour un serveur web de commerce électronique destiné à attirer des millions de clients du monde entier. LE protocole TLS s’appuie donc sur une infrastructure À clé publique, qui utilise deux clés pour le chiffrement des données , quand une clé de la paire chiffre les données, seule l’autre clé de la paire peut la déchiffrer. Le principal avantage de cette conception est que le chiffrement peut être effectué sans nécessiter l’échange sécurisé de clés de chiffrement.
Une infrastructure à clé publique utilise une technique où l’une des clés est conservée privée et n’est disponible que pour le principal auquel il est inscrit, tandis que l’autre clé est rendue publique pour toute personne à accéder. Si quelqu’un souhaite envoyer un message privé au propriétaire d’une paire de clés, le message peut être chiffré avec la clé publique et seule la clé privée peut être utilisée pour déchiffrer le message.
Les paires de clés sont également utilisées pour vérifier l’intégrité des données envoyées. Pour ce faire, le propriétaire de la paire de clés peut attacher une signature numérique aux données avant de l’envoyer. La création d’une signature numérique implique le calcul d’un hachage des données et le chiffrement du hachage avec la clé privée. Toute personne qui utilise la clé publique pour déchiffrer la signature numérique est assurée que la signature numérique ne doit provenir que de la personne propriétaire de la clé privée. En outre, le destinataire peut calculer un hachage des données à l’aide du même algorithme que l’expéditeur et si le hachage calculé correspond à celui envoyé dans la signature numérique, le destinataire peut être certain que les données n’ont pas été modifiées après sa signature numérique.
L’un des inconvénients de l’utilisation d’une infrastructure à clé publique pour le chiffrement de données à volume élevé est ses performances relativement lentes. En raison des mathématiques intensives impliquées, le chiffrement et le déchiffrement des données à l’aide d’un chiffrement asymétrique qui dépend d’une paire de clés peut être jusqu’à 1 000 fois plus lent que le chiffrement et le déchiffrement à l’aide d’un chiffrement symétrique qui dépend uniquement d’une seule clé. TLS utilise donc une infrastructure à clé publique uniquement pour générer des signatures numériques et pour négocier la clé unique spécifique à la session qui sera utilisée à la fois par le client et le serveur pour le chiffrement et le déchiffrement des données en bloc. TLS prend en charge un large éventail de chiffrements symétriques à clé unique, et des chiffrements supplémentaires peuvent être ajoutés à l’avenir.
Pour plus d’informations sur le protocole de négociation TLS, consultez protocole de négociation TLS.
Pour plus d’informations sur le chiffrement derrière le protocole TLS, consultez Cryptography Essentials.
Certificats X.509
Un problème critique qui doit être géré par une infrastructure à clé publique est la possibilité de faire confiance à l’authenticité de la clé publique utilisée. Lorsque vous utilisez une clé publique émise à une société avec laquelle vous souhaitez faire des affaires, vous voulez être certain que la clé appartient réellement à l’entreprise plutôt qu’à un voleur qui veut découvrir votre numéro de carte de crédit.
Pour garantir l’identité d’un principal contenant une paire de clés, le principal est émis un certificat X.509 par une autorité de certification (CA). Ce certificat contient des informations qui identifient le principal, contiennent la clé publique du principal et sont signées numériquement par l’autorité de certification. Cette signature numérique indique que l’autorité de certification croit que la clé publique contenue dans le certificat appartient réellement au principal identifié par le certificat.
Et comment faire confiance à l’autorité de certification ? Étant donné que l’autorité de certification elle-même contient un certificat X.509 signé par une autorité de certification de niveau supérieur. Cette chaîne de signatures de certificat se poursuit jusqu’à ce qu’elle atteigne une autorité de certification racine, qui est une autorité de certification qui signe ses propres certificats. Si vous approuvez l’intégrité de l’autorité de certification racine d’un certificat, vous devez être en mesure d’approuver l’authenticité du certificat lui-même. Par conséquent, la sélection d’autorités de certification racines que vous êtes prêt à approuver est un devoir important pour un administrateur système.
Certificats clients
Lorsque les protocoles de couche transport de sécurité ont d’abord émergé, leur objectif principal était de garantir qu’un client se connectait à un serveur authentique et contribue à protéger la confidentialité des données en transit. Toutefois, SSL 3.0 et TLS 1.0 incluent également la prise en charge de la transmission du certificat d’un client pendant la négociation du protocole. Cette fonctionnalité facultative permet l’authentification mutuelle du client et du serveur.
La décision d’utiliser un certificat client doit être prise dans le contexte de l’application. Les certificats clients ne sont pas nécessaires si l’exigence principale consiste à authentifier le serveur. Toutefois, si l’authentification du client est essentielle, le certificat d’un client peut être utilisé plutôt que de s’appuyer sur l’authentification personnalisée au sein de l’application. L’utilisation de certificats clients est préférable à l’authentification personnalisée, car elle donne aux utilisateurs un scénario d’authentification unique.
Utilisation de TLS dans COM
TLS prend uniquement en charge le niveau d’emprunt d’identité (RPC_C_IMP_LEVEL_IMPERSONATE). Si COM négocie TLS en tant que service d’authentification sur un proxy, COM définit le niveau d’emprunt d’identité pour emprunter l’identité, quel que soit le processus par défaut. Pour que l’emprunt d’identité fonctionne correctement dans TLS, le client doit fournir un certificat X.509 au serveur et le serveur doit avoir ce certificat mappé à un compte d’utilisateur particulier sur le serveur. Pour plus d’informations, consultez le guide pas à pas pour mapper des certificats à des comptes d’utilisateur.
TLS ne prend pas en charge . Si un indicateur de cloaking et tls sont spécifiés dans un appel CoInitializeSecurity ou un appel IClientSecurity ::SetBlanket, E_INVALIDARG est retourné.
TLS ne fonctionne pas avec le niveau d’authentification défini sur Aucun. La négociation entre le client et le serveur examine le niveau d’authentification défini par chacun et choisit le paramètre de sécurité supérieur pour la connexion.
Les paramètres de sécurité pour TLS peuvent être définis en appelant CoInitializeSecurity et CoSetProxyBlanket. Les sections suivantes décrivent les nuances impliquées dans l’établissement de ces appels.
Comment un serveur définit la couverture de sécurité
Si un serveur souhaite utiliser TLS, il doit spécifier Schannel (RPC_C_AUTHN_GSS_SCHANNEL) comme service d’authentification dans le paramètre asAuthSvc de CoInitializeSecurity. Pour empêcher les clients de se connecter au serveur à l’aide d’un service d’authentification moins sécurisé, le serveur doit spécifier uniquement Schannel comme service d’authentification lorsqu’il appelle CoInitializeSecurity. Le serveur ne peut pas modifier la couverture de sécurité une fois qu’il a appelé CoInitializeSecurity.
Pour utiliser TLS, les paramètres suivants doivent être spécifiés lorsqu’un serveur appelle CoInitializeSecurity:
- pVoid doit être un pointeur vers un objet IAccessControl ou un pointeur vers un SECURITY_DESCRIPTOR. Il ne doit pas être NULL ou un pointeur vers un AppID.
- cAuthSvc ne peut pas être 0 ou -1. Les serveurs COM ne choisissent jamais Schannel quand cAuthSvcest -1.
-
asAuthSvc doit spécifier Schannel comme service d’authentification possible. Pour ce faire, définissez les paramètres de SOLE_AUTHENTICATION_SERVICE suivants pour le membre Schannel de l'SOLE_AUTHENTICATION_LIST:
- dwAuthnSvc doit être RPC_C_AUTHN_GSS_SCHANNEL.
- dwAuthzSvc doit être RPC_C_AUTHZ_NONE. Actuellement, elle est ignorée.
- pPrincipalName doit être un pointeur vers un CERT_CONTEXT, casté en tant que pointeur vers OLECHAR, qui représente le certificat X.509 du serveur.
- dwAuthnLevel indique le niveau d’authentification minimal accepté par les clients pour une connexion réussie. Il ne peut pas être RPC_C_AUTHN_LEVEL_NONE.
- dwCapabilities ne doit pas avoir l’indicateur de EOAC_APPID défini. L’indicateur EOAC_ACCESS_CONTROL doit être défini si pVoid pointe vers un objet IAccessControl ; elle ne doit pas être définie si pointe vers un SECURITY_DESCRIPTOR. Pour les autres indicateurs qui peuvent être définis, consultez CoInitializeSecurity.
Pour plus d’informations sur l’utilisation de CoInitializeSecurity, consultez Définition de la sécurité à l’échelle du processus avec CoInitializeSecurity.
Comment un client définit la couverture de sécurité
Si un client souhaite utiliser TLS, il doit spécifier Schannel (RPC_C_AUTHN_GSS_SCHANNEL) dans sa liste de services d’authentification dans le paramètre pAuthList de CoInitializeSecurity. Si Schannel n’est pas spécifié comme service d’authentification possible lorsque CoInitializeSecurity est appelé, un appel ultérieur à CoSetProxyBlanket (ou IClientSecurity ::SetBlanket) échoue s’il tente de spécifier Schannel comme service d’authentification.
Les paramètres suivants doivent être spécifiés lorsqu’un client appelle CoInitializeSecurity:
- dwAuthnLevel spécifie le niveau d’authentification par défaut que le client souhaite utiliser. Il ne peut pas être RPC_C_AUTHN_LEVEL_NONE.
- dwImpLevel doivent être RPC_C_IMP_LEVEL_IMPERSONATE.
-
pAuthList doit avoir les paramètres de SOLE_AUTHENTICATION_INFO suivants en tant que membre de la liste :
- dwAuthnSvc doit être RPC_C_AUTHN_GSS_SCHANNEL.
- dwAuthzSvc doit être RPC_C_AUTHZ_NONE.
- pAuthInfo est un pointeur vers un CERT_CONTEXT, casté en tant que pointeur vers void, qui représente le certificat X.509 du client. Si le client n’a pas de certificat ou ne souhaite pas présenter son certificat au serveur, pAuthInfo doit être NULL et une connexion anonyme est tentée avec le serveur.
- dwCapabilities est un ensemble d’indicateurs qui indiquent des fonctionnalités client supplémentaires. Pour plus d’informations sur les indicateurs à définir, consultez CoInitializeSecurity.
Pour plus d’informations sur l’utilisation de CoInitializeSecurity, consultez Définition de la sécurité à l’échelle du processus avec CoInitializeSecurity.
Comment un client change la couverture de sécurité
Si un client souhaite utiliser TLS mais modifier la couverture de sécurité après avoir appelé CoInitializeSecurity, il doit appeler CoSetProxyBlanket ou IClientSecurity ::SetBlanket avec des paramètres similaires à ceux utilisés dans l’appel à CoInitializeSecurity, avec les différences suivantes :
- pServerPrincName indique le nom principal du serveur, au format msstd ou fullsic. Pour plus d’informations sur ces formats, consultez noms de principaux. Si le client a le certificat X.509 du serveur, il peut trouver le nom du principal en appelant RpcCertGeneratePrincipalName.
- pAuthInfo est un pointeur vers un CERT_CONTEXT, casté en tant que pointeur vers RPC_AUTH_IDENTITY_HANDLE, qui représente le certificat X.509 du client. Si le client n’a pas de certificat ou ne souhaite pas présenter son certificat au serveur, pAuthInfo doit être NULL et une connexion anonyme est tentée avec le serveur.
- dwCapabilities se compose d’indicateurs qui indiquent des fonctionnalités client supplémentaires. Seuls quatre indicateurs peuvent être utilisés pour modifier les paramètres de couverture de sécurité : EOAC_DEFAULT, EOAC_MUTUAL_AUTH, EOAC_ANY_AUTHORITY (cet indicateur est déconseillé) et EOAC_MAKE_FULLSIC. Pour plus d’informations, consultez CoSetProxyBlanket.
Pour plus d’informations sur l’utilisation de CoSetProxyBlanket, consultez Paramètre de sécurité au niveau du proxy d’interface.
Exemple : le client modifie la couverture de sécurité
L’exemple suivant montre comment un client peut modifier la couverture de sécurité pour prendre en charge une demande du serveur pour que le client fournisse son certificat X.509. Le code de gestion des erreurs est omis pour la concision.
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();
}
Rubriques connexes