I've recently seen a little discussion on CFTalk about importing SSL certificates into the JVM keystore used by the JVM under ColdFusion MX in order to connect to SSL enabled resources, such as LDAP servers or Web Servers while using either the tags CFLDAP, CFHTTP, or CFINVOKE. I've also found myself having to do this for the first time recently. During that process I stumbled on what turned out to be a bug in the JVM 1.4.2-b28 that ships with ColdFusion MX 6.1 by default.
I saved the SSL certificate to my ColdFusion directory runtime/jre/lib/security, as shown in this image. When using that JVM's keytool utility, described here in the Sun documentation, to import the certificate, I received an error indicating that the certificate which I exported from the SSL website was not valid, and I knew that was incorrect as someone else had just imported the same certificate their machine.
keytool error: java.lang.Exception: Input not an X.509 certificate
I learned that this was a known issue in some early 1.4.2 Sun JVMs, so I downloaded the most recent JVM from Sun, v. 1.4.2_05. I then configured ColdFusion MX to run on this new JVM, and tried again. This time the keytool imported the certificate without complaint, and the command keytool -storepass changeit -list -keystore cacerts confirmed the alias for my certificate. CFHTTP calls to the particular SSL enabled website now worked successfully.
Note that the cacerts keystore that comes with ColdFusion already contains about 128 certificates types from well known certificate authorities, so if you wanted to consume the page https://login.yahoo.com with CFHTTP it would work out of the box without having to import any extra certificate. You should only need to import a site's SSL certificate if the site does not use one of the certs already in the cacerts file in CFMX.
The Sun 1.4.2_05 JDK comes with a cacerts keystore that has about 25 cert types built in, so you'd probably want to swap that cacerts file with the one found under ColdFusion's root directory. If you choose to not run ColdFusion MX on the newer JVM, you could copy CFMX's cacerts file to the newer JVM's jre/lib/security directory to overwrite the existing one, then complete the steps to import the SSL certificate into the that cacerts keystore file, and then copy that cacerts file back under ColdFusion's runtime/jre/lib/security directory. Restart ColdFusion and the imported certificate will be ready for use.
A good litmus test is that if your CFHTTP call to an SSL site fails with the following error (cfdump of cfhttp variable), then you should import that certificate into the keystore file cacerts:
Filecontent Connection Failure
Mimetype Unable to determine MIME type of file.
Statuscode Connection Failure. Status code unavailable.<
For convenience, I wrote a set of batch files to be used on Windows when working with the keytool utility. They save a fair bit of typing. One batch file for example requires that you set 4 parameters for the JAVA_HOME, cert name & cert alias, and the keytool password. You can download the collection of bat files to customize yourself here.
An example of the import batch file is shown here:
echo
echo This will import an X.509 SSL certificate into the keystore for the JVM
specified
echo
echo Press Control+C to abort.
pause
SETLOCAL
rem -------------------------------------------------
rem 1) SET COLDFUSION JVM'S JAVA_HOME HERE
rem THIS SHOULD BE THE JVM USED FOR COLDFUSION MX
rem -------------------------------------------------
set JAVA_HOME=C:j2sdk1.4.2_05
rem -------------------------------------------------
rem 2) SET THE CERTIFICATE NAME AND ALIAS HERE
rem -------------------------------------------------
set CERT_NAME=mycert.cer
set CERT_ALIAS=mycert
rem -------------------------------------------------
rem 3) SET THE KEYTOOL PASSWORD HERE
rem -------------------------------------------------
set KEYTOOL_PASS=changeit
rem -------------------------------------------------
rem DO NOT EDIT BELOW THIS LINE
rem -------------------------------------------------
set JAVA_SECURITY=%JAVA_HOME%jrelibsecurity
set CERT=%JAVA_SECURITY%\%CERT_NAME%
%JAVA_HOME%jreinkeytool -import -trustcacerts -keystore %JAVA_SECURITY%cacerts
-storepass %KEYTOOL_PASS% -noprompt -alias %CERT_ALIAS% -file %CERT%
ENDLOCAL
pause
Exporting the SSL certificate (on Windows)
Using the keytool to import a certificate
There is a Sun SDK bug in early version of 1.4.2 JVM where the keytool doesn't work. You must download a recent JDK such as JDK 1.4.2_05 from java.sun.com.
Other resources for using the keytool include:
Updated May 2, 2007: Adding examples for use with *nix:
List All (listkeys.sh)
2JAVA_HOME=/opt/AppServer/java
3JAVA_SECURITY=$JAVA_HOME/jre/lib/security
4$JAVA_HOME/jre/bin/keytool -storepass changeit -list -keystore $JAVA_SECURITY/cacerts > keytool_list_result.txt
5cat keytool_list_result.txt
Import my certificate bogart9.cer then list to confirm (importkeys.sh)
2MYCERT_NAME=bogart9.cer #should be in jre/lib/security
3MYCERT_ALIAS=bogart9
4JAVA_HOME=/opt/AppServer/java
5JAVA_SECURITY=$JAVA_HOME/jre/lib/security
6CERT=$JAVA_SECURITY/$MYCERT_NAME
7$JAVA_HOME/jre/bin/keytool -import -trustcacerts -keystore $JAVA_SECURITY/cacerts -storepass changeit -noprompt -alias $MYCERT_ALIAS -file $CERT
8echo Keytool has imported $MYCERT_ALIAS into $JAVA_SECURITY/cacerts
9./listkeys.sh | grep $MYCERT_ALIAS
C:CFusionMX
untimejrelibsecurity>....inkeytool -import -trustcacerts -keystore cacerts -storepass changeit -noprompt -alias mycert -file mycert.cer
(view image) ErrorDetail I/O Exception: peer not authenticated
@echo off
1#!/bin/sh
1#!/bin/sh
Comments are not allowed for this entry.
#1 by Geoffrey Barth on 10/25/04 - 3:31 PM
#2 by Steven Erat on 10/25/04 - 4:02 PM
See: http://java.sun.com/j2se/1.4.2/docs/tooldocs/windo...;
Regarding CFHTTP, the certificate you`re importing isn`t really tied to the webserver that is connected to ColdFusion. The certificate you`re importing is the certificate of the target SSL enabled website that you`re making a request to with the CFHTTP tag. If that target SSL website happens to be on the same machine, then still you would just treat it as though it were remote.
Also, if the CF doesn`t have a valid certificate for the target SSL site, then you`ll get a I/O Peer Not Authenticated error. I don`t know about any problems with a certificate mismatch error.
#3 by Dave Cordes on 11/9/04 - 6:35 PM
Thanks.
#4 by Steven Erat on 11/12/04 - 6:01 PM
I`d have to take the error message at face value... "peer not authenticated". This indicats a security problem probably due to not having the remote target website`s certificate already in the ColdFusion cacerts certificate store.
Try saving the JetPay certificate by clicking the lock icon on their website, and use that along with my instructions to import the cert.
Then try again.
-Steve
#5 by Doug Hughes on 2/17/05 - 8:12 PM
#6 by Steven Erat on 2/17/05 - 8:25 PM
#7 by Geoff Caras on 2/24/05 - 1:57 PM
We started this due to problems getting a cert installed.
please advise!!!
#8 by Paul Bradley on 5/19/05 - 8:20 PM
This was a very informative BLOG, thanks.
I was wondering if you know of a workaround for CFHTTP when posting to https:// where the certificate name on the SSL does not match the host name.
When attempting this, I receive an Error Detail of I/O Exception: Name in certificate `www.domainname.com` does not match host name `xx.xx.xx.xx`
The cert in question is in my keystore.
I am running MX7 on Win XP Pro.
Any guidance is appreciated.
Sincerely,
Paul Bradley
#9 by Steven Erat on 5/19/05 - 9:40 PM
It seems to me that the purpose of the certificate is to validate that www.company.com is really company.com and not cracker.com for example. Although if the certificate is for foo.company.com and you`re having a problem with bar.company.com, then you`d probably want to consult with the Certificate Authority on the best way to generate a certificate for the domain level company.com so it will match each of the PTR records for that domain.
#10 by Adam Reid on 7/4/05 - 9:48 AM
CF is using its default JVM and if I run this command it appears in the trusted cert list:
keytool -list -keystore ../lib/security/cacerts
javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated
at com.sun.net.ssl.internal.ssl.SSLSessionImpl.getPeerCertificateChain(DashoA6275)
at HTTPClient.HTTPConnection.sendRequest(HTTPConnection.java:2949)
at HTTPClient.HTTPConnection.handleRequest(HTTPConnection.java:2767)
at HTTPClient.HTTPConnection.setupRequest(HTTPConnection.java:2559)
at HTTPClient.HTTPConnection.Get(HTTPConnection.java:916)
#11 by Adam Reid on 7/4/05 - 11:59 AM
Installed a good one and it worked first time.
Cheers, Adam
#12 by suresh rajasekaran on 1/4/06 - 4:15 PM
getting connection failure. could you please help??
#13 by suresh rajasekaran on 1/4/06 - 4:16 PM
port="413" proxyserver="205.158.171.208" proxyport="443" proxypassword="1ishwar1"
#14 by Paul on 1/4/06 - 4:59 PM
I noticed that the SSL cert on the address you are trying to access, [a href="https://205.158.171.208/misc/vingt.cfm" target="_blank"]https://205.158.171.208/misc/vingt.cfm[/a], is not a 100% valid certificate.
I have had problems trying to access a secure site via CFHTTP if the SSL cert does not match 100% I never did find a solution.
Try accessing a non-secure URL on the same IP via CFHTTP. If you can access the non-secure URL but not the secure URL this may be a root cause.
Also, verify your CFHTTP parameters. Try the URL using http: and PORT=443. Maybe that is part of the problem.
#15 by Steven Erat on 2/27/06 - 2:46 PM
" But I figured out the solution! Since I know that the certificate is called "pbx" and I now have it installed on the application server (which in this case is the client - SwitchVox is the server) .. still follow? .. I make an entry in the "hosts" file of the application server called pbx and point it to the IP address of SwitchVox."
[a href="http://www.docnotes.net/002323.html" target="_blank"]http://www.docnotes.net/002323.html[/a]
#16 by Jackie on 8/15/06 - 7:42 PM
I need to access an SLL URL thru CFHTTP for payment authorizations. I must build in a contingency to fail over to a second URL if I can`t connect to the first. The URLs are similar to:
[a href="https://blah1.paymentech.net" target="_blank"]https://blah1.paymentech.net[/a] and [a href="https://blah2.paymentech.net" target="_blank"]https://blah2.paymentech.net[/a]
Connecting to blah1 is fine. Connecting to blah2 gives the dreaded I/O Exception (mismatch). If I browse to blah2 in IE, I get the typical security alert so I`m fairly certain the cert name the problem in CF. I tried installing the cert thru JVM to cacert as outlined in this post. Any other suggestions? HELP!!!!
#17 by Mario on 11/14/06 - 8:36 PM
method="post"
port="xxx"
proxyserver="xxxx"
proxyport="xxx"
I am having the same problem but I am using BlueDragon and CFMX. I am trying to connect to vendor using CFHTTP to send a XML file. The vendor keeps telling me that I am faliing the SSL handshake on his side. I was told by him that I needed to purchase a certificate form a trusted third party which we did (Verisign). This certificate was installed by my server team but I am refused connection at the vendor.
Do I need to export the vendors certificate and install it on my WebLogic server using the Keytool.
#18 by Steven Erat on 11/14/06 - 9:11 PM
First, imagine a simple HTTPS connection between a browser and server. A user in a browser types in the URL of a website beginning with https and the brower makes the request. Lets assume that the server is using SSLv2. The request gets to the server and it replies with a message header stating it supports SSLv2 and sends its certificate. The browser receives the SSL certificate, inspects it, and negotiates the session key to be used. The handshake part of the session key negotiation is done with asymmetric cryptography, and when a session key is agreed on by the browser and the client they switch to symmetric cryptography while using the session key, because symmetric key crypto is faster than assymetric. Anyway, the SSLv2 handshake does not require that the browser send its own certificate back to the server. In SSLv2 only the server has to prove its identity to the client, the browser.
However, in SSLv3 not only does the server have to prove its identity to the client, but the client or browser also has to identify itself to to the server.and it does that by sending its own certificate. So there are two certifcates involved in SSLv3, one on the server and one on the client.
In the case of a CFHTTP connection, the client is ColdFusion and the server is the target url such as [a href="https://httpmailbox1...." target="_blank"]https://httpmailbox1....[/a] So if the vendor says that you need to send a certificate then the vendor is isdirectly telling you that they support SSLv3 not SSLv2.
This conclusion is bad news unfortunately. ColdFusion MX 7 does not yet support SSLv3 for its protocol tags such as CFHTTP, CFINVOKE, CFLDAP, etc. Importing your new Verisign certificate into ColdFusion`s cacerts file will do nothing for your problem. The cacerts file under ColdFusion is which Certificate Authorities ColdFusion will trust for the other end of the CFHTTP connection such as the scenario above for SSLv2. In order to support SSLv3 ColdFusion would have to perform an HTTP Request, get the HTTP Reply from the SSL website including the other end`s SSL certificate, and then ColdFusion would have to send its own certificate back to the other server to say "Hey, I`m such and such ColdFusion server here, really I am". But ColdFusion does not yet do that.
You may need to seek a third party solution, perhaps a Java custom extension that did SSLv3 and HTTP for you, and you could integrate that into your ColdFusion application.
#19 by Steve on 10/2/07 - 9:55 AM
See also:
[a href="http://www.talkingtree.com/blog/index.cfm/2004/11/......" target="_blank"]http://www.talkingtree.com/blog/index.cfm/2004/11/......[/a]
#20 by Rob Gonda on 10/29/07 - 8:26 PM
Cheers
#21 by Jose on 2/4/08 - 8:44 PM
The server returned a fault:
Fault code: wsse:InvalidSecurity
Fault string: Security Data : General security error (Error during certificate path validation: timestamp check failed); nested exception is: java.security.cert.CertPathValidatorException: timestamp check failed; internal cause is: java.security.cert.CertificateExpiredException: NotAfter: Thu Jan 31 13:39:15 PST 2008
As the message indicates it seems as if the SSL cert has expired but it hasn`t (it expires in 2009). Also I just registered it with the keytool utility and it still fails. I have a feeling the keytool file is getting "confused" since this SSL cert was renewed recently. (It may be still looking at the previous cert). How can I tell the system to look at the current/new cert??
TIA
#22 by Donrico on 5/29/08 - 6:24 PM
I know this thread is really old, but, thank you, thank you. I used the information here to get my CF scheduleTasks to with my SSL website... and the server administrators said it wouldn`t work pppshhaa. what do they know. awesome
donrico
#23 by Steven Erat on 5/29/08 - 7:15 PM
#24 by Stephanie on 7/21/08 - 9:14 PM
My development server is running cf mx 7. I followed the instructions to import the certificate to cacerts but still getting Connection Failure error.
I have a postmessage.cfm that returns "OK" if someone HTTP Post something to it.
OK#chr(13)##chr(10)#
Here is testpostmessage.cfm to test postmessage.cfm is getting the data I post.
Here is the result
Charset [empty string]
ErrorDetail I/O Exception: Default SSL context init failed: null
Filecontent Connection Failure
Header [undefined struct element]
Mimetype Unable to determine MIME type of file.
Responseheader
struct [empty]
Statuscode Connection Failure. Status code unavailable.
Text YES
I ran keytool to list all the certificates and confirmed that my certificate is in the list. CF Services are restarted. Is there anything else I can do to ensure the certificate is applied properly? Please help.
Thanks,
Stephanie
#25 by Stephanie on 7/21/08 - 9:16 PM
#26 by Michael Kirshner on 8/1/08 - 7:16 PM
We`re running MX7 on Windows XP Pro. I`ve upgraded the Java to 1.4.2_11 to solve the daylight saving time issue...
I have a CFDOCUMENT tag with several CFCHARTS embedded within the PDF that is being created. When we added the SSL Cert, the charts are no longer displayed. This phenomenon is described in: [a href="http://coldfused.blogspot.com/2005/11/missing-imag...es-in-cfdocument.html" target="_blank">http://coldfused.blogspot.com/2005/11/missing-imag......" target="_blank"]http://coldfused.blogspot.com/2005/11/missing-imag......[/a]
The solution seems to be to import the certificate to the trusted certficate store (runtime/lib/trustStore).
Well I successfully imported the new cert into C:CFusionMX7
untimelib rustStore and rebooted the CF App Service. On testing the page, the PDF wasn`t created with the charts.
I then successfully imported the new cert into C:CFusionMX7
untimejrelibsecuritycacerts and rebooted the CF App Service. That too failed to embed the charts.
I even imported the new cert into C:CFusionMX7
untimej2sdk1.4.2_11jrelibsecuritycacerts. After restarting the service, the charts still did not display.
What am I missing?
Thank you.
#27 by Alex on 8/8/08 - 6:35 PM
untimejrelibsecurity folder, as well as the C:j2sdk*jrelibsecurity folder. I had it in the CF folder, but not the main JRE folder. A simple copy of the cacerts file fixed the problem.
-AH
#28 by Quinn on 8/12/08 - 6:12 PM
i`ve googled and googled but there does not appear to be a clear solution (other than getting a new cert).
any ideas?
#29 by Ben Nadel on 12/17/08 - 3:05 PM
I am asking because I am getting the following error:
java.io.IOException: Keystore was tampered with, or password was incorrect
I don`t see how anyone could have tampered with it, so I think it must be a password issue?
#30 by Ben Nadel on 12/17/08 - 3:27 PM
"The initial password of the "cacerts" keystore file is "changeit". System administrators should change that password and the default access permission of that file upon installing the SDK."
Hmm, ok.
#31 by Steven Erat on 12/17/08 - 4:20 PM
I think the Java engineers were trying to be too clever when providing a default SDK with keystore password of changeit, expecting everyone to get it....
"CHANGE - IT" was a hint to do just that, change the default password to a secure one.
#32 by Ben Nadel on 12/17/08 - 4:25 PM
#33 by Steven Erat on 12/17/08 - 5:43 PM
#34 by Chandu on 4/2/09 - 2:37 AM
#35 by edward on 9/22/09 - 1:28 PM
#36 by edward on 9/22/09 - 1:29 PM
#37 by B. Hendel on 10/22/09 - 3:42 AM
-Brian