260 likes | 290 Views
X.509 certificate management in .NET. -Vamsi sri Harsha Vidala. Introduction. A public key certificate is digitally signed document that is commonly used for authentication and secure exchange of information on open networks.
E N D
X.509 certificate management in .NET -Vamsi sri Harsha Vidala
Introduction • A public key certificate is digitally signed document that is commonly used for authentication and secure exchange of information on open networks. • A certificate securely binds a public key to the entity that holds the corresponding private key. • Certificates are digitally signed by the issuing certification authority (CA). They create a trust relationship between two unknown entities.
Overview of X.509 certificates Entities involved in X.509 certificate management. • Subjects and End Entities. • Certification Authority(CA). • Registration Authority(RA).
Certificate Management Operations Certificate Repository Cert. publish End Entity “Out-of-Band” loading Initial Registration/ Certification. Key Pair recovery. Key Pair Update. Certificate Update. Revocation Request. Cert. “USERS” Cert. Mgmt Entities RA Cert. publish “Out-of-Band” publication CA Cert. publish Cross-certification. Cross- Certificate Update. CA-2
Certificate Management Operations • CA establishment. • End entity initialization. • Certification: • Initial registration/Certification. • Key pair Update. • Certificate Update. • CA Key pair update. • Cross-certification Request. • Cross-certificate Update.
Operations(contd.) • Certificate/CRLdiscovery operations. • Certificate Publication • CRL Publication • Recovery operations • Key-pair recovery • PSE operations
Note: The most widely accepted format for certificates is defined by the ITU-T X.509 version 3 international standards. The certificates are encoded using OSI ASN.1 DER. Formats for X.509 Certificate
Using X.509 Certificates in .NET application • Create and manage X.509 Certificate • Sign a SOAP Message Using an X.509 Certificate • Verify Digital Signatures of SOAP Messages Signed by an X.509 Certificate
STEP I Create and manage X.509 Certificate
Obtain X.509 Certificate • Purchase a certificate from a certificate authority, such as VeriSign, Inc • Set up our own certificate service and have a certificate authority sign the certificates • Set up our own certificate service and do not have the certificates signed Note: Whichever approach we take, the recipient of the SOAP request containing the X.509 certificate must trust the X.509 certificate.
Creating and configuring X.509 Certificate • Create certificate using makecert.exe cmd>makecert -n "CN=TempCA" -r -sv TempCA.pvk TempCA.cer • Import the created certificate using MMC in to the certificate store Import the certificate TempCA.cer using MMC in to "Trusted Root Certificate Authorities" folder • Export the created certificate to outside world by creating and distributing pfx file using pvk2pfx tool cmd>pvk2pfx -pvk TempCA.pvk -spc TempCA.cer • Define access permission for X.509 certificate cmd>winhttpcertcfg -g -c LOCAL_MACHINE\MY -s TempCA -a ASPNET
Make certificates accessible to application • Specify the certificate store that application uses to obtain X.509 certificates <configuration> <microsoft.web.services2> <security> <x509 storeLocation="CurrentUser" /> </security> </microsoft.web.services2> </configuration> • Specify the account under which application is running read access to the file containing the private key associated with the X.509 certificate. <processModel enable="true|false"userName="username" password="password" />
Default accessibility for certificates Default Locations of certificate store: Usage of private key:
STEP II Sign a SOAP Message Using an X.509 Certificate
Config file settings for using X.509 certificates • <policyDocumentxmlns="http://schemas.microsoft.com/wse/2003/06/Policy"> • <mappings xmlns:wse="http://schemas.microsoft.com/wse/2003/06/Policy"> • <endpoint uri="http://www.cohowinery.com/SaleWidgets.asmx"> • <defaultOperation> • <request policy="#policy-c0a22319-6b89-49ff-9b82-bdbac5f04618" /> • <response policy="#policy-c0a22319-6b89-49ff-9b82-bdbac5f04618" /> • <fault policy="#policy-c0a22319-6b89-49ff-9b82-bdbac5f04618" /> • </defaultOperation> • </endpoint> • </mappings> • <policies • … • </policies> • </policyDocument>
Config file settings for using X.509 certificates • <policies xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> • <wsp:Policy wsu:Id="policy-c0a22319-6b89-49ff-9b82-bdbac5f04618" • xmlns:wsp="http://schemas.xmlsoap.org/ws/2002/12/policy" • xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/03/addressing" > • <wssp:Integrity wsp:Usage="wsp:Required"xmlns:wssp="http://schemas.xmlsoap.org/ws/2002/12/secext"> • <wssp:TokenInfo> • <SecurityToken xmlns="http://schemas.xmlsoap.org/ws/2002/12/secext"> • <wssp:TokenType> • http://schemas.xmlsoap.org/ws/2003/12/kerberos/Kerberosv5ST • </wssp:TokenType> • <wssp:TokenIssuer>COHOWINERY</wssp:TokenIssuer> • <wssp:Claims> • <wssp:ServiceName>host/computer1@cohowinery.com</wssp:ServiceName> • </wssp:Claims> • </SecurityToken> • </wssp:TokenInfo> • <wssp:MessageParts Dialect="http://schemas.xmlsoap.org/2002/12/wsse#part"> • wsp:Body() wsp:Header(wsa:To) wsp:Header(wsa:Action) wsp:Header(wsa:MessageID) wsp:Header(wsa:From) • </wssp:MessageParts> • </wssp:Integrity> • </policies>
Retrieve certificate from store • public X509SecurityToken GetSecurityToken() • { • X509SecurityToken securityToken = null; • X509CertificateStore store = X509CertificateStore.CurrentUserStore( X509CertificateStore.MyStore); • bool open = store.OpenRead(); • try • { • byte[] certHash = {0x98, 0xec, 0x08, 0x4b, 0xa5, 0x7a, 0x6c, 0x2f, 0x39, 0x26, 0xb3, 0x0a, 0x58, 0xbf, 0x65, 0x25, 0x61, 0xc5, 0x64, 0x59}; • X509CertificateCollection certs = store.FindCertificateByHash(certHash); • Microsoft.Web.Services2.Security.X509.X509Certificate cert = • ((Microsoft.Web.Services2.Security.X509.X509Certificate) certs[0]); • if (cert == null) • … • else if (!cert.SupportsDigitalSignature || (cert.Key == null)) • … • else • { • securityToken = new X509SecurityToken(cert); • } • } • finally • { • if (store != null) • store.Close(); • } • return securityToken; • }
Code for signing SOAP messages • Call GetSecurityToken() to retrieve certificate X509SecurityToken signatureToken = GetSecurityToken(); • Get the SoapContext method for the SOAP request made to the Web service. Service1 svc = new Service1(); SoapContext requestContext = svc.RequestSoapContext; • Add the client's X.509 certificate to the SOAP header.requestContext.Security.Tokens.Add(signatureToken); • Create a new instance of the MessageSignature class by using the X.509 certificate just added to the SOAP header. MessageSignature sig = new MessageSignature(signatureToken); • Add the digital signature to the SOAP header. RequestContext.Security.Elements.Add(sig); • Specify the TTL for the SOAP message requestContext.Security.Timestamp.TtlInSeconds = 60; • Call the Web service. svc.sayHello();
STEP III Verify Digital Signatures of SOAP Messages Signed by an X.509 Certificate
Configure application to validate digital signatures for incoming SOAP messages • Export and Import the CA certificate chain • Add a reference to the Microsoft.Web.Services2 assembly • When the SOAP message recipient is a Web service client, this configuration entry is not required. Else configure web.config as below: • <configuration> • <system.web> • <webServices> • <soapExtensionTypes> • <add type="Microsoft.Web.Services2.WebServicesExtension, • Microsoft.Web.Services2,Version=2.0.0.0, Culture=neutral, • PublicKeyToken=31bf3856ad364e35" • priority="1" group="0"/> • </soapExtensionTypes> • </webServices> • </system.web> • </configuration>
Code to verify if SOAP Body is signed public string CheckSOAPBody() { SoapContext requestContext = RequestSoapContext.Current; // Verify that a SOAP request was received. if (requestContext == null) { throw new ApplicationException("Either a non-SOAP " + "request was received or WSE is not properly " + "installed for the Web application hosting the " + "Web service."); } // Check if the Soap Message is Signed. if (!IsMessageSigned(requestContext)) { throw new ApplicationException("The request is not signed."); } return "sucess"; }
Code to verify digital signature of SOAP request private bool IsMessageSigned(SoapContext context) { foreach (ISecurityElement element in context.Security.Elements) { if (element is MessageSignature) { // The given context contains a Signature element. MessageSignature sig = element as MessageSignature; if ((sig.SignatureOptions & SignatureOptions.IncludeSoapBody) != 0) { // The SOAP Body is signed. return true; } } } return false; }
References http://www.ietf.org/rfc/rfc2510.txt http://msdn.microsoft.com/en-us/library/system.security.cryptography.x509certificates.x509certificate(VS.71).aspx http://msdn.microsoft.com/en-us/library/ms820022.aspx http://support.microsoft.com/kb/315588 http://msdn.microsoft.com/en-us/library/ms819944.aspx http://www.codeproject.com/KB/cpp/X509Certificate.aspx http://www.codeproject.com/KB/WCF/Senthil.aspx