Context
You are implementing Brokered Authentication in an application
deployed on a Microsoft Windows platform, with security implemented at the
message layer. A Web Service using Web Services Enhancements (WSE) is
processing requests from requestors. Requestors and services must use a
standards-based security token that is portable across organizations and
security boundaries. The solution chosen must be able to provide a complete set
of security features, including Mutual Authentication, Data Origin
Authentication and Confidentiality.
Implementation Strategy
Use the X509SecurityToken
with WSE 2.0 policy to access certificates and use them for signing and
encryption. The X509SecurityToken object
accesses the subject's private key, which is used to sign the message. The
message is then encrypted using the service's public key, found in its X.509
certificate. The service decrypts the message using its private key, and
verifies the XML signature using the public key of the subject, which is found
in the subjects X.509 certificate, included with the message.
Note:
For an overview of WSE policy, see
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wse/html/748c1b28-b6b8-483e-97dc-c726ef5a01c5.asp
This pattern assumes that the Service's certificate has already
been obtained by the client out of band, so that
both the Sender and Recipient can access the
certificate from a local certificate store.
Approach
The process section of the
"Brokered Authentication - X.509 PKI" pattern
describes how a certificate can be used for authentication. The following tasks
represent a recommended approach for implementing message layer authentication
using X.509 certificates:
Each task is divided into specific steps. While you are strongly encouraged to
follow the recommendations, the steps contain enough information to allow you
to tailor a solution to your specific needs.
Initialize and Send a Message with X.509 Certificate Information
This task has six steps that are recommended:
1. Retrieve
the Service’s certificate.
2. Retrieve
the Subject's certificate.
3. Attach
the certificate to a message.
4. Sign
the message.
5. Encrypt
the message.
6. Send the message to the Service.
The steps are summarized in Figure 1 below:
Figure 1
Initializing and sending a message with X.509 certificate
information
Each step is discussed in more detail below:
Step One: Retrieve the
Service’s certificate
The Requestor needs to access the X.509 certificate of the service
to encrypt the request message. The requestor can retrieve the Service's
certificate from a local certificate store without the need for code, by using
policy. If a confidentiality assertion is defined to use the Service's
certificate, WSE policy retrieves the certificate from the certificate store
automatically.
You can use either the Key Identifier or the Subject Name to
identify the certificate. However, you should avoid using the Subject Name,
because a Subject can have several certificates with the same Subject Name. The
WSE policy engine will throw an application exception when more than one
certificate is found with the same subject name in the certificate store.
Note: Certificate
information such as the subject name or KeyIdentifier
can be obtained using the WSE X.509 Certificate Tool. You can also use the MMC
snap-in to obtain the subject name. However, when a subject name is fully
canonicalized, it must be reversed when is specified as a subject name in a WSE
policy assertion. For example, a subject name obtained from the MMC Snap-In as
“CN=bob, DC=Microsoft, DC=com” must be reversed when specified in policy, to
read as “DC=com, DC=Microsoft, CN=bob.” The WSE X.509 Certificate Tool reverses
the order automatically.
Step Two: Retrieve the
Subject's X.509 certificate and Private Key
The Requestor needs to access the X.509 certificate and private key
of the Subject. The private key is to sign the message, while the X.509
certificate is used to provide the public key, which is used to verify the
signature at the service. The service account used by the application sending
the request must have appropriate rights to access the private key, and is used
to sign the message.
Note: The
WSE X.509 Certificate Tool can be used to view private key file properties
and set access
permissions for the service account
.
The X.509 certificate is retrieved automatically by the
X509SecurityTokenManager class when policy assertions are either being
enforced for outbound messages or verified for incoming messages. For more
information on accessing the certificate store, see
Security Considerations.
The X509SecurityToken object
accesses the subject's private key.
Step Three: Attach the
Subject's Certificate to the message
Policy is used to sign the message, and so WSE automatically
attaches the Subject’s certificate to the request message.
Step Four: Sign the Message
The message is signed using the Subject’s private key. You can
choose to sign one or more portions of the message, such as the address header,
or the entire message. An XML signature is created using a signature algorithm
that computes a checksum from the data to be signed and encrypts the checksum
with the private key of the Subject. When the XML signature is validated, the
data used to create the signature is also validated, providing Data Origin
Authentication.
To use policy assertions in WSE 2.0, the location of a policy cache
file must be specified in the application’s configuration file. The following
configuration file lines provide an example of specifying a name and location
for the application’s policy cache file:
<configuration>
<microsoft.web.services2>
<policy>
<cache name="Configuration/PolicyCache.config" />
</policy>
</microsoft.web.services2>
</configuration>
The example below shows a sample Integrity policy assertion from an
application’s policy cache that is used to sign various parts of a request
message:
…
<wssp:Integrity wsp:Usage="wsp:Required">
<wssp:TokenInfo>
<wssp:SecurityToken wse:IdentityToken="true">
<wssp:TokenType>http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3</wssp:TokenType>
<wssp:TokenIssuer>CN=Root
Agency</wssp:TokenIssuer>
<wssp:Claims>
<wssp:X509Extension OID=
"2.5.29.14"MatchType="wssp:Exact">gBfo0147lM6cKnTbbMSuMVvmFY4=</wssp:X509Extension>
</wssp:Claims>
</wssp:SecurityToken>
</wssp:TokenInfo>
<wssp:MessageParts
Dialect="http://schemas.xmlsoap.org/2002/12/wsse#part">wsp:Body()
wsp:Header(wsa:Action) wsp:Header(wsa:FaultTo) wsp:Header(wsa:From)
wsp:Header(wsa:MessageID) wsp:Header(wsa:RelatesTo) wsp:Header(wsa:ReplyTo)
wsp:Header(wsa:To) wse:Timestamp()</wssp:MessageParts>
</wssp:Integrity>
<!-MessagePredicate Assertion verifies that all message parts are present on message -->
<wsp:MessagePredicate wsp:Usage="wsp:Required" Dialect="http://schemas.xmlsoap.org/2002/12/wsse#part">
wsp:Body() wse:Timestamp()
</wsp:MessagePredicate>
…
Step Five: Encrypt the Message
The entire message or portions of the message can be encrypted
using the public key from the Service's X.509 certificate. At a minimum, the
XML signature should be encrypted to help protect against offline attacks.
The
Confidentiality policy assertion in WSE 2.0 only encrypts a message
body, and so a custom policy assertion (ConfidentialityEx) must also be used to
encrypt the message signature.
When message data is
encrypted in WSE using an X509SecurityToken,
asymmetric encryption is used to encrypt a one-time symmetric key which in turn
is used to encrypt the data. When message data is encrypted using the Service's
certificate information the SubjectKeyIdentifier
of the certificate is also added to the message by WSE. The Service owns the
certificate, and so this is all the information that is necessary for the
Service to access the appropriate private key and decrypt the message.
Encrypting the request in this way protects sensitive data, if the
requestor is deceived into calling an illegitimate service. As the intended
message recipient, only the correct Web service is capable of decrypting the
message with its private key.
The following policy example encrypts a message using a
Confidentiality assertion and encrypts the message signature using a custom
policy assertion:
<wssp:Confidentiality wsp:Usage="wsp:Required">
<wssp:KeyInfo>
<!--The
SecurityToken element within the KeyInfo element describes which token type
must be used for Encryption.-->
<wssp:SecurityToken>
<wssp:TokenType>http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3</wssp:TokenType>
<wssp:TokenIssuer>CN=Root
Agency</wssp:TokenIssuer>
<wssp:Claims>
<wssp:SubjectNameMatchType="wssp:Exact">CN=MySerivce</wssp:SubjectName>
<wssp:X509Extension OID=
"2.5.29.14"MatchType="wssp:Exact">4sCW7DkUpO0spxinO6DEUS9fRVk=</wssp:X509Extension>
</wssp:Claims>
</wssp:SecurityToken>
</wssp:KeyInfo>
<wssp:MessageParts
Dialect="http://schemas.xmlsoap.org/2002/12/wsse#part">wsp:Body()</wssp:MessageParts>
</wssp:Confidentiality>
<wsisa:ConfidentialityEx
wsp:Usage="wsp:Required">
<wssp:MessageParts
Dialect="http://schemas.xmlsoap.org/2002/12/wsse#part">
wsp:Signature()
</wssp:MessageParts>
</wsisa:ConfidentialityEx>
A custom policy assertion enforces encryption of signatures, by
implementing the IPolicyEnforcer interface,
using the Enforce() method. The
details of implementing a custom policy assertion are beyond the scope of this
document, but an example can be found on the Microsoft Patterns & Practices
website:
http://msdn.microsoft.com/library/default.asp?url=/library/enus/dnpag2/html/MSWSIBSP.asp
Step Six: Send the Message to
the Service
After the message has been signed and encrypted, it is sent to the Service.
This task has five recommended steps:
1. Verify
the Certificate Trust Chain
2. Check
the Certificate Revocation Status
3. Decrypt
the Message
4. Verify
the XML Signature.
5. Initialize and
send a response to the requestor
The steps are summarized in Figure 2 below:
Figure 2
Authenticating a subject using an X.509 certificate and digital
signature
Step One: Verify the
Certificate Trust Chain
WSE 2.0 verifies the trust chain of certificates by default. The
setting to control this behavior is controlled by the
verifyTrust attribute of the <x509>
element in the application’s configuration file, under WSE security.
The following XML example shows WSE 2.0 X.509 security
configuration settings in an application configuration file:
<microsoft.web.services2>
<security>
<x509
storeLocation="LocalMachine" verifyTrust="true" />
</security>
</microsoft.web.services2>
WSE must be able to recognize an issuing CA as trusted, to verify
the certificate trust chain for a Subject’s X.509 certificate. WSE trusts
recognizes an issuing CA as trusted based on the X.509 certificate used to
endorse the Subject's certificate. WSE will recognize the issuing CA’s
certificate as a trusted root for a certificate chain if the CA’s X.509
certificate is installed into the machine certificate store under the “Trusted
Root Certification Authorities” folder.
The high level steps for installing a certificate chain are as
follows:
1. Export
the certificate chain from the CA. This is dependant on the type of CA used.
2. Import
the certificate chain into a local certificate store.
Note: For more information on managing certificates and
trust chains, see the X.509 Security
Primer.
Step Two: Check the Certificate
Revocation Status
While this step is optional it is also strongly recommended. As
discussed in the
"Brokered
Authentication - X.509 PKI" pattern there are two types of checks. One is to validate
the certificate itself and the other is to make sure the certificate came from
an expected source.
WSE policy checks the revocation status of the certificate by
checking if the certificate is on a Certificate Revocation List (CRL) published
by the CA. The CRL can be obtained out-of-band by downloading it from a CA and
importing it into a local certificate store, where it is accessible from WSE.
You can also check the validity of the certificate by accessing the CA
directly. However, this approach relies on the CA being online and accessible
by the Web service. There is also a performance cost associated with accessing
the CA directly on every call, so you should download the CRL instead of
accessing it directly from the CA. By default, WSE verifies the revocation
status of X.509 certificates.
Note: For more information about CRLs see the
X.509 Security Primer.
Step
Three
: Decrypt the Message
To decrypt messages with WSE you should define a confidentiality
assertion in WSE policy for incoming messages
that identifies the token used to encrypt the messages, and rejects
messages that do not have specific message parts encrypted with the correct
token.
When WSE receives a message that has been encrypted WSE policy
automatically decrypts the message using the following steps:
1. The
Certificate's SubjectKeyIdentifier that
was included in the message is used to access the private key of the
certificate.
2. The
private key is used to decrypt the asymmetrically encrypted, one-time symmetric
key, that was sent with the message.
3. The
symmetric key is then used to decrypt the message data using a Symmetric
decryption algorithm.
The following XML example shows a confidentiality assertion that
would be included in Service’s incoming request policy, to require that only
messages that have been encrypted using the public key from the specified X.509
certificate will be accepted. The custom policy assertion used by the requestor
to encrypt the signature for the request message is also used by the service to
decrypt the message signature on incoming messages.
<wssp:Confidentiality wsp:Usage="wsp:Required">
<wssp:KeyInfo>
<!--The
SecurityToken element within the KeyInfo element describes which token type
must be used for Encryption.-->
<wssp:SecurityToken>
<wssp:TokenType>http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3</wssp:TokenType>
<wssp:TokenIssuer>CN=Root
Agency</wssp:TokenIssuer>
<wssp:Claims>
<wssp:SubjectNameMatchType="wssp:Exact">CN=My
Service</wssp:SubjectName>
<wssp:X509Extension
OID=
"2.5.29.14"MatchType="wssp:Exact">4sCW7DkUpO0spxinO6DEUS9fRVk=</wssp:X509Extension>
</wssp:Claims>
</wssp:SecurityToken>
</wssp:KeyInfo>
<wssp:MessageParts
Dialect="http://schemas.xmlsoap.org/2002/12/wsse#part">wsp:Body()</wssp:MessageParts>
</wssp:Confidentiality>
<wsisa:ConfidentialityEx wsp:Usage="wsp:Required">
<wssp:MessageParts
Dialect="http://schemas.xmlsoap.org/2002/12/wsse#part">wsp:Signature()
</wssp:MessageParts>
</wsisa:ConfidentialityEx>
Note: Policy alone will not stop someone from sending an
unencrypted message. However, it will reject a message at the server if it is
not encrypted. A sender can also implement a policy assertion to require
outbound messages to be encrypted when a requestor encrypts a request message.
Step Four: Verify the XML
Signature
Once the message is received by a Service, the XML signature is
verified automatically by WSE policy, which validates it using the public key
that was sent with the message. If the message data had been signed this step
also validates the origin of that data, providing Data Origin Authentication.
X.509 by itself does not provide a means to establish a security principal for a Subject represented in an X.509 certificate. Unless you intend to accept requests from every holder of a valid X.509 certificate, that can be verified through a trust chain to a trusted root certificate, you must somehow limit the population down to those from whom you would expect to receive messages. There are several approaches that can be used to accomplish this task:
To use policy assertions in an application, you must specify the
name and location of the policy cache file that the application will use in the
application’s configuration file, as shown in the following code example:
<configuration>
<microsoft.web.services2>
<policy>
<cache name="Configuration/PolicyCache.config"/>
</policy>
</microsoft.web.services2>
</configuration>
The following Integrity assertion requires that an incoming request
is signed by a subject identified by their X.509 certificate base 64 Key
identifier:
<wssp:Integrity wsp:Usage="wsp:Required">
<wssp:TokenInfo>
<!--The
SecurityToken element within the TokenInfo element describes which token type
must be used for Signing.-->
<wssp:SecurityToken
wse:IdentityToken="true">
<wssp:TokenType>http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3</wssp:TokenType>
<wssp:TokenIssuer>CN=Root
Agency</wssp:TokenIssuer>
<wssp:Claims>
<wssp:SubjectNameMatchType="wssp:Exact">CN=My
Client</wssp:SubjectName>
<wssp:X509Extension OID=
"2.5.29.14"MatchType="wssp:Exact">gBfo0147lM6cKnTbbMSuMVvmFY4=</wssp:X509Extension>
</wssp:Claims>
</wssp:SecurityToken>
</wssp:TokenInfo>
<wssp:MessageParts
Dialect="http://schemas.xmlsoap.org/2002/12/wsse#part">wsp:Body()
wsp:Header(wsa:Action) wsp:Header(wsa:FaultTo) wsp:Header(wsa:From)
wsp:Header(wsa:MessageID) wsp:Header(wsa:RelatesTo) wsp:Header(wsa:ReplyTo)
wsp:Header(wsa:To) wse:Timestamp()</wssp:MessageParts>
</wssp:Integrity>
In the above example, the Subject’s X.509 certificate is identified
by the integrity policy assertion, using the certificate’s base 64 key
identifier specified in the <wssp:X509Extension>element
as an Object ID (OID). The X.509 extension that allows use of the Key
identifier OID in the above example is the only X.509 extension supported by
WSE 2.0 by default. The base 64 key identifier for an X.509 certificate can be
obtained using the X.509 Certificate Tool included in the WSE 2.0 SDK.
Step Five: Intialize and send a
response to the requestor (optional)
If the Service returns a secure response to the requestor, the same process described in the previous steps is used for the response message between the service and the requestor, with the roles of the requestor and service reversed. The service initiates and sends the response, signing the response with the service’s private key and encrypting with the subject’s X.509 certificate public key. The requestor processes the response in the same manner as the service processed the request, decrypting the response with the subject’s private key and verifying the service’s signature with the service’s X.509 certificate.
Resulting Context
The following benefits, liabilities, and security considerations
are associated with the use of the X.509 CA as an Authentication Broker.
Benefits
Liabilities
Security Considerations
Microsoft Confidential. © 2005 Microsoft Corporation.
All rights reserved. By using or providing feedback on these materials, you
agree to the attached license agreement.