Working with Certificates
To program Windows Communication Foundation (WCF) security, X.509 digital certificates are commonly used to authenticate clients and servers, encode messages, and digitally sign messages. This topic briefly explains certificate features and how to use them in WCF, and includes links to topics that explain these concepts further or that show how to accomplish common tasks using WCF and certificates.
In brief, a digital certificate is a part of a public key infrastructure (PKI), which is a system of digital certificates, certificate authorities, and other registration authorities that verify and authenticate the validity of each party involved in an electronic transaction through the use of public key cryptography. A certificate authority issues certificates and each certificate has a set of fields that contain data, such as subject (the entity to which the certificate is issued), validity dates, issuer, and public key. In WCF, each of these properties is processed as a Claim, and each claim is further divided into two types: identity and right. For more information, see Managing Claims and Authorization with the Identity Model. For more information about implementing a PKI, see Best Practices for Implementing a Microsoft Windows Server 2003 Public Key Infrastructure.
A primary function of the certificate is to authenticate the identity of the subject to others. A certificate also contains the public key of the subject, while the subject retains the private key. Anyone can use the public key to encrypt a message. However, both keys are required to decrypt a message; therefore, only the holder of the private key can decrypt messages. The public key can be used to encrypt messages to the owner of the certificate. Only the owner has access to the private key, so only the owner can decrypt those messages.
Certificates must be issued by a certificate authority, which is often a third-party issuer of certificates. On a Windows domain, a certificate authority is included that can be used to issue certificates to computers on the domain.
For more information about certificates, see Certificates.
To work with certificates, it is often necessary to view them and examine their properties. This is easily done with the Microsoft Management Console (MMC) snap-in tool. For more information, see How to: View Certificates with the MMC Snap-in. Additional how-to documents for using the tool can be found in Httpcfg Overview.
Certificates are found in stores. Two major store locations exist that are further divided into sub-stores. If you are the administrator on a computer, you can view both major stores by using the MMC snap-in tool. Non-administrators can view only the current user store.
The local machine store. This contains the certificates accessed by machine processes, such as ASP.NET. Use this location to store certificates that authenticate the server to clients.
The current user store. Interactive applications typically place certificates here for the computer's current user. If you are creating a client application, this is where you typically place certificates that authenticate a user to a service.
These two stores are further divided into sub-stores. The most important of these when programming with WCF include:
Trusted Root Certification Authorities. You can use the certificates in this store to create a chain of certificates, which can be traced back to a certificate authority certificate in this store.
Note: The local computer implicitly trusts any certificate placed in this store, even if the certificate does not come from a trusted third-party certificate authority. For this reason, do not place any certificate into this store unless you fully trust the issuer and understand the consequences.
Personal. This store is used for certificates associated with a user of a computer. Typically this store is used for certificates issued by one of the certificate authority certificates found in the Trusted Root Certification Authorities store. Alternatively, a certificate found here may be self-issued and trusted by an application.
For more information about certificate stores, see Certificate stores.
Selecting a Store
Selecting where to store a certificate depends how and when the service or client runs. The following general rules apply:
If the service is a Windows service, a service running in "server" mode without any user interface under a Network service account, use the local machine store. Note that administrator privileges are required to install certificates into the local machine store.
If the service or client is embedded in an application that runs under a user account, then use the current user store.
Stores are protected by access control lists (ACLs), just like folders on a computer. When creating a service hosted by Internet Information Services (IIS), the ASP.NET process runs under the ASP.NET account. That account must have access to the store that contains the certificates a service uses. Each of the major stores is protected with a default access list, but the lists can be modified. If you create a separate role to access a store, you must grant that role access permission. To learn how to modify the access list using the WinHttpCertConfig.exe tool, see How to: Create Temporary Certificates for Use During Development. For more information about using client certificates with IIS, see How to call a Web service by using a client certificate for authentication in an ASP.NET Web application.
Chain Trust and Certificate Authorities
Digital certificates are used to authenticate an entity by relying on a chain of trust. The chain is formed from top to bottom, with a root authority at the top. You can view any certificate's chain using the MMC snap-in by double-clicking any certificate, then clicking the Certificate Path tab. The root authority certificate at the top of a certificate chain is self-issued. That is, the issuer and the entity to which the certificate is issued are the same. For more information about importing certificate chains for a Certificate Authority, see How to: Specify the Certificate Authority Certificate Chain Used to Verify Signatures (WCF).
|Any issuer can be designated a trusted root authority by placing the issuer's certificate in the trusted root authority certificate store.|
Disabling Chain Trust
When creating a new service, you may be using a certificate that is not issued by a trusted root certificate, or the issuing certificate itself may not be in the Trusted Root Certification Authorities store. For development purposes only, you can temporarily disable the mechanism that checks the chain of trust for a certificate. To do this, set the CertificateValidationMode property to either PeerTrust or PeerOrChainTrust. Either mode specifies that the certificate can either be self-issued (peer trust) or part of a chain of trust. You can set the property on any of the following classes.
You can also set the property using configuration. The following elements are used to specify the validation mode:
The CertificateValidationMode property also enables you to customize how certificates are authenticated. By default, the level is set to ChainTrust. To use the Custom value, you must also set the CustomCertificateValidatorType attribute to an assembly and type used to validate the certificate. To create a custom validator, you must inherit from the abstract X509CertificateValidator class.
When creating a custom authenticator, the most important method to override is the Validate method. For an example of custom authentication, see the X.509 Certificate Validator sample. For more information, see Custom Credential and Credential Validation.
Using Makecert.exe to Build a Certificate Chain
The Certificate Creation Tool (Makecert.exe) creates X.509 certificates and private key/public key pairs. You can save the private key to disk and then use it to issue and sign new certificates, thus simulating a hierarchy of chained certificates. The tool is intended for use only as an aid when developing services and should never be used to create certificates for actual deployment. When developing an WCF service, use the following steps to build a chain of trust with Makecert.exe.
To build a chain of trust with Makecert.exe
Create a temporary root authority (self-signed) certificate using the MakeCert.exe tool. Save the private key to the disk.
Use the new certificate to issue another certificate that contains the public key.
Import the root authority certificate into the Trusted Root Certification Authorities store.
For step-by-step instructions, see How to: Create Temporary Certificates for Use During Development.
Which Certificate to Use?
Common questions about certificates are which certificate to use, and why. The answer depends on whether you are programming a client or service. The following information provides a general guideline and is not an exhaustive answer to these questions.
Service certificates have the primary task of authenticating the server to clients. One of the initial checks when a client authenticates a server is to compare the value of the Subject field to the Uniform Resource Identifier (URI) used to contact the service: the DNS of both must match. For example, if the URI of the service is "http://www.contoso.com/endpoint/" then the Subject field must also contain the value "www.contoso.com".
Note that the field can contain several values, each prefixed with an initialization to indicate the value. Most commonly, the initialization is "CN" for common name, for example, "CN = www.contoso.com". It is also possible for the Subject field to be blank, in which case the Subject Alternative Name field can contain the DNS Name value.
Also note the value of the Intended Purposes field of the certificate should include an appropriate value, such as "Server Authentication" or "Client Authentication".
Client certificates are not typically issued by a third-party certificate authority. Instead, the Personal store of the current user location typically contains certificates placed there by a root authority, with an intended purpose of "Client Authentication". The client can use such a certificate when mutual authentication is required.
Online Revocation and Offline Revocation
Every certificate is valid only for a given period of time, called the validity period. The validity period is defined by the Valid from and Valid to fields of an X.509 certificate. During authentication, the certificate is checked to determine whether the certificate is still within the validity period.
Certificate Revocation List
At any time during the validity period, the certificate authority can revoke a certificate. This can occur for many reasons, such as a compromise of the private key of the certificate.
When this occurs, any chains that descend from the revoked certificate are also invalid, and are not trusted during authentication procedures. To find out which certificates are revoked, each issuer publishes a time- and date-stamped certificate revocation list (CRL). The list can be checked using either online revocation or offline revocation by setting the RevocationMode or DefaultRevocationMode property of the following classes to one of the X509RevocationMode enumeration values: X509ClientCertificateAuthentication, X509PeerCertificateAuthentication, X509ServiceCertificateAuthentication, and the IssuedTokenServiceCredential classes. The default value for all properties is Online.
You can also set the mode in configuration using the revocationMode attribute of both the <authentication> of <clientCertificate> Element (of the serviceBehaviors section) and the <authentication> of <clientCertificate> Element (of the endpointBehaviors section).
The SetCertificate Method
In WCF, you must often specify a certificate or set of certificates a service or client is to use to authenticate, encrypt, or digitally sign a message. You can do this programmatically by using the SetCertificate method of various classes that represent X.509 certificates. The following classes use the SetCertificate method to specify a certificate.
The SetCertificate method works by designating a store location and store, a "find" type (x509FindType parameter) that specifies a field of the certificate, and a value to find in the field. For example, the following code creates a ServiceHost instance and sets the service certificate used to authenticate the service to clients with the SetCertificate method.
Uri baseAddress = new Uri("http://cohowinery.com/services"); ServiceHost sh = new ServiceHost(typeof(CalculatorService), baseAddress ); sh.Credentials.ServiceCertificate.SetCertificate( StoreLocation.LocalMachine, StoreName.My, X509FindType.FindBySubjectName, "cohowinery.com");
Multiple Certificates with the Same Value
A store may contain multiple certificates with the same subject name. This means that if you specify that the x509FindType is FindBySubjectName or FindBySubjectDistinguishedName, and more than one certificate has the same value, an exception is thrown because there is no way to distinguish which certificate is required. You can mitigate this by setting the x509FindType to FindByThumbprint. The thumbprint field contains a unique value that can be used to find a specific certificate in a store. However, this has its own disadvantage: if the certificate is revoked or renewed, the SetCertificate method fails because the thumbprint is also gone. Or, if the certificate is no longer valid, authentication fails. The way to mitigate this is to set the x590FindType parameter to FindByIssuerName and specify the issuer's name. If no particular issuer is required, you can also set one of the other X509FindType enumeration values, such as FindByTimeValid.
Certificates in Configuration
You can also set certificates by using configuration. If you are creating a service, credentials, including certificates, are specified under the serviceBehaviors section. When you are programming a client, certificates are specified under the endpointBehaviors section.
Mapping a Certificate to a User Account
A feature of IIS and Active Directory is the ability to map a certificate to a Windows user account. For more information about the feature, see Map certificates to user accounts.
For more information about using Active Directory mapping, see Mapping Client Certificates with Directory Service Mapping.
With this capability enabled, you can set the MapClientCertificateToWindowsAccount property of the X509ClientCertificateAuthentication class to true. In configuration, you can set the mapClientCertificateToWindowsAccount attribute of the <authentication> element to true, as shown in the following code.
<serviceBehaviors> <behavior name="MappingBehavior"> <serviceCredentials> <clientCertificate> <authentication certificateValidationMode="None" mapClientCertificateToWindowsAccount="true" /> </clientCertificate> </serviceCredentials> </behavior> </serviceBehaviors>
Mapping an X.509 certificate to the token that represents a Windows user account is considered an elevation of privilege because, once mapped, the Windows token can be used to gain access to protected resources. Therefore, domain policy requires the X.509 certificate to comply with its policy prior to mapping. The SChannel security package enforces this requirement.
When using .NET Framework version 3.5 or later, WCF ensures the certificate conforms to domain policy before it is mapped to a Windows account.
In the first release of WCF, mapping is done without consulting the domain policy. Therefore it is possible that older applications that used to work when running under the first release, fails if the mapping is enabled and the X.509 certificate does not satisfy the domain policy.