Two way authorization with PFX file

I have a problem with two-way authentication. I Use tomcat6 as a server and as a client I try IE, Firefox and my own java application.

The problem occurs using PFX certificates given to me by someone else. I have to use them as a client certificate, so i just add it to trusted certs on server and use it on browser in user certificates. The problem is that i get bad_certificate alert.

I have succeeded in doing two-way ssl by generating my own certificates for server and client and adding public keys as trusted in both keystores etc...

When i watch wireshark logs i see, that server sends good certificate request but client sends empty Certificate (11 bytes length packet) instead of 500+ bytes when i used my own generated cert.

What can be the problem? Why client does not send good cert? :(


Well, the first thing to check is to see if Tomcat is configured correctly to request a certificate from the client for the path in question. For Tomcat 6, this means you should have a Connector configured in conf/server.xml something like this:

<Connector port="443" protocol="HTTP/1.1" SSLEnabled="true"
           maxThreads="150" scheme="https" secure="true"
           keystoreFile="${user.home}/.keystore" keystorePass="password"
           truststoreFile="conf/truststore" truststorePass="password"
           clientAuth="true" sslProtocol="TLS" />

The truststoreFile & truststorePass are important - if you just add "clientAuth=true" without including these two parameters, you'll see all sorts of strange behavior (and no warning that you did anything wrong). The truststoreFile must point to a legitimate JKS file that lists the CA's that you trust to sign the client certificates. If Tomcat is configured correctly, the browser should pop up a dialog to the user along the lines of: "The website requires a client certificate" along with a list of all certificates that have been imported to the browser. If you don't see this, there's something wrong with your Tomcat setup.

It sounds like you've got that set up correctly, but it's worth double-checking. Also, if you have it set up correctly, you will see a "certificate request" handshake message if you trace the connection in wireshark that lists the trusted CAs by distinguished name. Again, if you don't see this, check your Tomcat setup and most importantly the truststore.

The next thing would be to check the PKCS12 file itself. You can do this with:

openssl pkcs12 -in [path-to-pkcs12-file] -nokeys | openssl x509 -noout -subject -issuer

Make sure that the issuer's distinguished name matches one of the trustedCaCert entries in your trust store. This is sort of a hassle to do with the Java keytool, but you can double check using:

keytool -exportcert -keystore conf/truststore -alias [alias of trusted cert] | openssl x509 -noout -subject -inform der

If all of this checks out, but it's still not working, it's worth using openssl's s_client to troubleshoot, since you usually get a lot more troubleshooting information from it. To do so, you'll have to separate the key from the cert in the PKCS12 file:

openssl pkcs12 -in [PKCS12 file] -out [whatever].key
openssl s_client -tls1 -connect localhost:443 -cert [whatever].key -key [whatever].key

(You can use the same file for the "-cert" and "-key" argument because openssl is smart enough look for the "BEGIN CERTIFICATE" and "BEGIN RSA PRIVATE KEY" delimiters in the source files). I was having a frustrating problem with client certs that I couldn't figure out once until I used s_client and got a reminder that my client certificate had expired (which wasn't logged or output anywhere else).

Also, you might want to strongly consider shifting your configuration to use Apache over Tomcat - Apache is a lot more flexible, and gives you a lot more feedback when it comes to SSL confifguration than Tomcat is.


Take a closer look at your client certificates, in particular the X509v3 extensions "Key Usage" and "Extended Key Usage". They may be marked as not trusted for client authentication.

Using the openssl command-line tool:

$ openssl pkcs12 -in server-only.pfx -nokeys | openssl x509 -noout -purpose
Enter Import Password:
MAC verified OK
Certificate purposes:
SSL client : No
SSL client CA : No
SSL server : Yes
SSL server CA : No

This certificate is only signed for server authentication (normal HTTPS). For full details, use the -text option in openssl x509:

$ openssl pkcs12 -in server-only.pfx -nokeys | openssl x509 -noout -text
  [..snip..]
        X509v3 Key Usage: 
            Digital Signature, Key Encipherment
        X509v3 Extended Key Usage: 
            TLS Web Server Authentication
  [..snip..]

If this is the case, you're going to have to ask to get a new signed certificate that is marked for client authentication use.

链接地址: http://www.djcxy.com/p/21816.html

上一篇: 相互认证

下一篇: PFX文件的双向授权