Friday 22 March 2013

Webservices integration, using certificates to increase security (SSL).

What are SSL Certificates and how to use them? How to use SSL certificates to communicate to external secure webservices?
Types of certificates:
There are two types of certificates. In a two-way SSL connection, both certificates must exist:
  • Server certificate
  • Client Certificate
Server Certificate:
  • This certifies the web server
  • Customer has to pay for this certificate to their certification agency.
  • We do not care about this certificate on setup, just on execution.
  • This certificate must reside on their server.
  • File extension is usually .cer
  • Certificate must be signed by an approved CA (Certificate Authority), you can find a list of current CAs here: http://wiki.developerforce.com/index.php/Outbound_Messaging_SSL_CA_Certificates
Client Certificate:
  • This certifies the client.
  • This certificate can be self-signed or signed by a trusted CA for improved security (optional, not required).
  • There are two ways in which this client certificate can be created:
    • Created in their web server.
    • Created in your Salesforce ORG
The Client Certificate only has information on the receiving web server (the Salesforce server does not matter); therefore the same Client Certificate can be used regardless if the call is made from the production ORG or from the sandbox, as long as the destination server is the same.
Importing and using the client certificates
Client Certificate created in customer's web server (Legacy):
  • The keystore has to be built and the certificate is exported in PKCS12 format.
  • When this certificate is generated, a password is also created.
  • This certificate is embedded in the Apex code. Since it is just ASCII letters (Base64), it goes on a String variable.


This sample was taken from Apex Code Developer's Guide (Invoking Callouts Using Apex > Using Certificates > Using Certificates with SOAP Services):
docSample.DocSamplePort stub = new docSample.DocSamplePort();
stub.clientCert_x = 'MIIGlgIBAzCCBlAGCSqGSIb3DQEHAaCCBkEEggY9MIIGOTCCAe4GCSqGSIb3DQEHAaCCAd8EggHb'+
'MIIB1zCCAdMGCyqGSIb3DQEMCgECoIIBgjCCAX4wKAYKKoZIhvcNAQwBAzAaBBSaUMlXnxjzpfdu'+
'6YFwZgJFMklDWFyvCnQeuZpN2E+Rb4rf9MkJ6FsmPDA9MCEwCQYFKw4DAhoFAAQU4ZKBfaXcN45w'+
'9hYm215CcA4n4d0EFJL8jr68wwKwFsVckbjyBz/zYHO6AgIEAA==';
stub.clientCertPasswd_x = 'passwd'; // <<< Password for the keystore
String output = stub.InvokeWebservice();
  • The clientCert_x is the keystore certificate in PKCS12 format
  • The clientCertPasswd_x is the password used for the web server's keystore (when the certificate was added).
    • This Server must be certified using a 3rd Party Signed Certificate
    • The certificate being added to the keystore is the Keystore certificate.
  • The keystore owner must give the developer the certificate and the password.
    • We can't help if they don't want to share the password... The whole concept of using PKCS12 is to give access to the trusted parties.
    • They don't need to share the password of their server certificate, just the private key of the certificate
    • They should not have problems sharing the password of a self signed PKCS12 certificate
Client Certificate created in your Salesforce ORG (preferred way):
  • The certificate is generated in Salesforce (Setup > Administration Setup > Security Controls > Certificate and Key Management)
  • The certificate must them be installed on the web server’s keystore.
  • A link to this certificate is embedded in the Apex code.
Sample code:
docSample.DocSamplePort stub = new docSample.DocSamplePort();
stub.clientCertName_x = 'Certificate Name'; // <<< Salesforce’s certificate name
String output = stub.InvokeWebservice();
Who can sign Server Certificates?
When performing callouts from Salesforce over HTTPS, it is required that the remote server have an SSL certificate signed by a root certification authority (CA) trusted by the default keystore in Sun's JDK 6 and approved by Salesforce. A complete list is found here: http://wiki.developerforce.com/index.php/Outbound_Messaging_SSL_CA_Certificates.

For security purposes, Salesforce will not add any additional certificates to the trusted list. If the server certificate is not signed directly by a root CA, the server must also return any intermediate certificates to complete the trust chain to the root CA. The server or certificate vendor can assist with instructions to install local and intermediate certificates.
What certificate to use?
Basically, Both ;-)
  • Server Certificate must be used to certify the destination for your SOAP calls (web server).
  • Client Certificate is used in the handshake, at the start of the SOAP call.
  • You could have the Client Certificates signed by a CA, but this is not required.
How it works?
When SFDC makes a call to a secured server, it first tries to see if the server has a Server Certificate. If it does, then it sends the Client Certificate (and possibly a password, see samples above). If this Client Certificate is accepted by the web server, then the communication is valid and the data is sent ack and forth between SFDC and the web server.
Other information
openssl s_client -showcerts -connect <host>:<port>

0 comments:

Post a Comment

    Links