Discussion:
mutual authentication
Linus Kamb
2013-10-08 20:15:13 UTC
Permalink
Has anyone set up and used mutual authentication SSL with client
certificates (preferably with Glassfish, but any setup would do) and would
be willing to give me some pointers ?

I've been looking online for documentation and/or examples, but so far have
not found anything concrete or complete enough to get it working.

Ultimately I would like to use this for programmatic access to web services
(or at least considering doing that), but I thought first step would be to
get it to work with a browser. No love.

Any tips would be appreciated.

thanks,
Linus
Dennis Sosnoski
2013-10-08 20:44:22 UTC
Permalink
Hi Linus,

I've done this many times, though I'm not sure I ever set it up for a
browser. When using a plain Java client you just need to set up a
keyStore for the client certificate, along with a keyStore password, and
have the client certificate in the server's trustStore. I don't know how
Metro works, but on Tomcat you enable the client certificate request by
just using clientAuth="true". The server requests the certificate from
the client as part of the SSL establishment.

Incidentally, I've got a new article up on InfoQ that discusses how you
can keep your data secret when communicating:
http://www.infoq.com/articles/keeping-your-secrets I don't include
mutual authentication in there, but the same principles apply as with
standard SSL/TLS.

- Dennis
Post by Linus Kamb
Has anyone set up and used mutual authentication SSL with client
certificates (preferably with Glassfish, but any setup would do) and
would be willing to give me some pointers ?
I've been looking online for documentation and/or examples, but so far
have not found anything concrete or complete enough to get it working.
Ultimately I would like to use this for programmatic access to web
services (or at least considering doing that), but I thought first
step would be to get it to work with a browser. No love.
Any tips would be appreciated.
thanks,
Linus
Mitch Gitman
2013-10-08 21:20:32 UTC
Permalink
Building on what Dennis wrote


I like to look at two-way SSL authentication by breaking it up into two
problems:

1. The client trusting the server--to create the secure connection so the
client can pass its credentials.

2. The server authenticating the client.

Here's what I can recall from having to support and document this sort of
thing before in an SOA ecosystem. As Dennis writes, each JVM client is
going to have to pull the server's public key certificate into its keystore.

Then each client is going to have to create their own public/private key
pair using some authority the server trusts and then share the signed
public key certificate with the server. The server will have a persistence
store with its entire known universe of clients and their signed
certificates from which it can authenticate requests. I've done this with
SOAP, so the client would pass their credentials message-level (as opposed
to transport-level) in the header of the SOAP message according to the
WS-Security standard. I'm glossing over so much. Recalling everything that
had to be documented, this is a classic case of "the devil's in the
details."

And not that I'm saying this is a reason in itself to use SOAP. The client
could always pass its one-way hashed public key the way it would pass a
one-way hashed password via Thrift or SOAP or ProtoBuf using some
parameters the client and server agree to; I don't know of any established
practices for those lightweight protocols. I recently saw someone propose
taking a REST JSON message and break it up into a standard envelope
containing a header and a payload, just like you'd do with SOAP, and
frankly, I don't quite know yet what to make of that.

One other observation, and maybe this is stating the obvious. Once you get
to #2, you have a lot of choices how to get the client to authenticate
itself to the server.
Post by Dennis Sosnoski
**
Hi Linus,
I've done this many times, though I'm not sure I ever set it up for a
browser. When using a plain Java client you just need to set up a keyStore
for the client certificate, along with a keyStore password, and have the
client certificate in the server's trustStore. I don't know how Metro
works, but on Tomcat you enable the client certificate request by just
using clientAuth="true". The server requests the certificate from the
client as part of the SSL establishment.
Incidentally, I've got a new article up on InfoQ that discusses how you
http://www.infoq.com/articles/keeping-your-secrets I don't include mutual
authentication in there, but the same principles apply as with standard
SSL/TLS.
- Dennis
Has anyone set up and used mutual authentication SSL with client
certificates (preferably with Glassfish, but any setup would do) and would
be willing to give me some pointers ?
I've been looking online for documentation and/or examples, but so far
have not found anything concrete or complete enough to get it working.
Ultimately I would like to use this for programmatic access to web
services (or at least considering doing that), but I thought first step
would be to get it to work with a browser. No love.
Any tips would be appreciated.
thanks,
Linus
Mitch Gitman
2013-10-08 21:58:59 UTC
Permalink
Two corrections, not necessarily pertinent to the question. I wrote: "Thrift
or *SOAP* or ProtoBuf." I meant: "Thrift or *REST* or ProtoBuf." And about
credentials being sent message-level as opposed to transport-level, well,
they always are. I was thinking about the broader question of message-level
vs. transport-level security, and the SSL (where client is trusting server)
is doing the latter.
Post by Mitch Gitman
Building on what Dennis wrote

I like to look at two-way SSL authentication by breaking it up into two
1. The client trusting the server--to create the secure connection so the
client can pass its credentials.
2. The server authenticating the client.
Here's what I can recall from having to support and document this sort of
thing before in an SOA ecosystem. As Dennis writes, each JVM client is
going to have to pull the server's public key certificate into its keystore.
Then each client is going to have to create their own public/private key
pair using some authority the server trusts and then share the signed
public key certificate with the server. The server will have a persistence
store with its entire known universe of clients and their signed
certificates from which it can authenticate requests. I've done this with
SOAP, so the client would pass their credentials message-level (as opposed
to transport-level) in the header of the SOAP message according to the
WS-Security standard. I'm glossing over so much. Recalling everything that
had to be documented, this is a classic case of "the devil's in the
details."
And not that I'm saying this is a reason in itself to use SOAP. The client
could always pass its one-way hashed public key the way it would pass a
one-way hashed password via Thrift or SOAP or ProtoBuf using some
parameters the client and server agree to; I don't know of any established
practices for those lightweight protocols. I recently saw someone propose
taking a REST JSON message and break it up into a standard envelope
containing a header and a payload, just like you'd do with SOAP, and
frankly, I don't quite know yet what to make of that.
One other observation, and maybe this is stating the obvious. Once you get
to #2, you have a lot of choices how to get the client to authenticate
itself to the server.
Linus Kamb
2013-10-08 22:16:39 UTC
Permalink
Hi All,

Thanks for your responses.

I know there are many ways to authenticate the client. Using certs
started out as an exploratory exercise. (Now it's a WTF is going wrong?!?
problem.)

I'm sure there is some slap-myself-in-the-head detail that I've overlooked
or am getting wrong.

I have a client cert imported into FF and Chrome. I've imported that cert
into the server's trust store. Tried as well with independent (from
"regular" ssl port) listener with its own trust and key stores. FF
connection attempts just fail. Chrome says SSL_PROTOCOL_ERROR, which is at
least something. Other than that I get no error or log messages, and
browser network tools say nothing, and I can't tell if wireshark is telling
me anything useful. My feeling is that the failure is probably some damn
string name inconsistency somewhere, but I am not getting any clues.

thanks,
Linus
Post by Mitch Gitman
**
Two corrections, not necessarily pertinent to the question. I wrote: "Thrift
or *SOAP* or ProtoBuf." I meant: "Thrift or *REST* or ProtoBuf." And
about credentials being sent message-level as opposed to transport-level,
well, they always are. I was thinking about the broader question of
message-level vs. transport-level security, and the SSL (where client is
trusting server) is doing the latter.
Building on what Dennis wrote…
I like to look at two-way SSL authentication by breaking it up into two
1. The client trusting the server--to create the secure connection so the
client can pass its credentials.
2. The server authenticating the client.
Here's what I can recall from having to support and document this sort of
thing before in an SOA ecosystem. As Dennis writes, each JVM client is
going to have to pull the server's public key certificate into its keystore.
Then each client is going to have to create their own public/private key
pair using some authority the server trusts and then share the signed
public key certificate with the server. The server will have a persistence
store with its entire known universe of clients and their signed
certificates from which it can authenticate requests. I've done this with
SOAP, so the client would pass their credentials message-level (as opposed
to transport-level) in the header of the SOAP message according to the
WS-Security standard. I'm glossing over so much. Recalling everything that
had to be documented, this is a classic case of "the devil's in the
details."
And not that I'm saying this is a reason in itself to use SOAP. The
client could always pass its one-way hashed public key the way it would
pass a one-way hashed password via Thrift or SOAP or ProtoBuf using some
parameters the client and server agree to; I don't know of any established
practices for those lightweight protocols. I recently saw someone propose
taking a REST JSON message and break it up into a standard envelope
containing a header and a payload, just like you'd do with SOAP, and
frankly, I don't quite know yet what to make of that.
One other observation, and maybe this is stating the obvious. Once you
get to #2, you have a lot of choices how to get the client to authenticate
itself to the server.
Dennis Sosnoski
2013-10-08 22:55:11 UTC
Permalink
I thought you could get more details of the error from the browser. Just
to see what you're at, you are able to connect from the browser using
only server certificate, right?

One advantage to using a Java client is that you can turn on SSL debug
to show details of any problem (-Djavax.net.debug=ssl,handshake will
give you everything interesting). The code I linked to from the InfoQ
article does this - if you clone
https://github.com/dsosnoski/keep-secrets you can modify
com.sosnoski.certs.UseCert to use your trustStore, and can just set your
client keyStore using the system properties or create a KeyManager in
code and add it to the SSLContext init() call. This stackoverflow
question shows the details of setting up the KeyManager:
http://stackoverflow.com/questions/9179717/using-more-than-one-key-pair-in-ssl-socket-factory-connection

- Dennis
Post by Linus Kamb
Hi All,
Thanks for your responses.
I know there are many ways to authenticate the client. Using certs
started out as an exploratory exercise. (Now it's a WTF is going
wrong?!? problem.)
I'm sure there is some slap-myself-in-the-head detail that I've
overlooked or am getting wrong.
I have a client cert imported into FF and Chrome. I've imported that
cert into the server's trust store. Tried as well with independent
(from "regular" ssl port) listener with its own trust and key stores.
FF connection attempts just fail. Chrome says SSL_PROTOCOL_ERROR,
which is at least something. Other than that I get no error or log
messages, and browser network tools say nothing, and I can't tell if
wireshark is telling me anything useful. My feeling is that the
failure is probably some damn string name inconsistency somewhere, but
I am not getting any clues.
thanks,
Linus
Two corrections, not necessarily pertinent to the question. I
wrote: "Thrift or _SOAP_ or ProtoBuf." I meant: "Thrift or _REST_
or ProtoBuf." And about credentials being sent message-level as
opposed to transport-level, well, they always are. I was thinking
about the broader question of message-level vs. transport-level
security, and the SSL (where client is trusting server) is doing
the latter.
Building on what Dennis wrote…
I like to look at two-way SSL authentication by breaking it up
1. The client trusting the server--to create the secure
connection so the client can pass its credentials.
2. The server authenticating the client.
Here's what I can recall from having to support and document
this sort of thing before in an SOA ecosystem. As Dennis
writes, each JVM client is going to have to pull the server's
public key certificate into its keystore.
Then each client is going to have to create their own
public/private key pair using some authority the server trusts
and then share the signed public key certificate with the
server. The server will have a persistence store with its
entire known universe of clients and their signed certificates
from which it can authenticate requests. I've done this with
SOAP, so the client would pass their credentials message-level
(as opposed to transport-level) in the header of the SOAP
message according to the WS-Security standard. I'm glossing
over so much. Recalling everything that had to be documented,
this is a classic case of "the devil's in the details."
And not that I'm saying this is a reason in itself to use
SOAP. The client could always pass its one-way hashed public
key the way it would pass a one-way hashed password via Thrift
or SOAP or ProtoBuf using some parameters the client and
server agree to; I don't know of any established practices for
those lightweight protocols. I recently saw someone propose
taking a REST JSON message and break it up into a standard
envelope containing a header and a payload, just like you'd do
with SOAP, and frankly, I don't quite know yet what to make of
that.
One other observation, and maybe this is stating the obvious.
Once you get to #2, you have a lot of choices how to get the
client to authenticate itself to the server.
Linus Kamb
2013-10-08 23:17:42 UTC
Permalink
Thanks, Dennis. I'll check it out.

Yes, I can connect fine when client authentication is turned off.

I will see what adding that debug setting tells me.

thanks,
Linus
Post by Dennis Sosnoski
**
I thought you could get more details of the error from the browser. Just
to see what you're at, you are able to connect from the browser using only
server certificate, right?
One advantage to using a Java client is that you can turn on SSL debug to
show details of any problem (-Djavax.net.debug=ssl,handshake will give you
everything interesting). The code I linked to from the InfoQ article does
this - if you clone https://github.com/dsosnoski/keep-secrets you can
modify com.sosnoski.certs.UseCert to use your trustStore, and can just set
your client keyStore using the system properties or create a KeyManager in
code and add it to the SSLContext init() call. This stackoverflow question
http://stackoverflow.com/questions/9179717/using-more-than-one-key-pair-in-ssl-socket-factory-connection
- Dennis
Hi All,
Thanks for your responses.
I know there are many ways to authenticate the client. Using certs
started out as an exploratory exercise. (Now it's a WTF is going wrong?!?
problem.)
I'm sure there is some slap-myself-in-the-head detail that I've
overlooked or am getting wrong.
I have a client cert imported into FF and Chrome. I've imported that
cert into the server's trust store. Tried as well with independent (from
"regular" ssl port) listener with its own trust and key stores. FF
connection attempts just fail. Chrome says SSL_PROTOCOL_ERROR, which is at
least something. Other than that I get no error or log messages, and
browser network tools say nothing, and I can't tell if wireshark is telling
me anything useful. My feeling is that the failure is probably some damn
string name inconsistency somewhere, but I am not getting any clues.
thanks,
Linus
Post by Mitch Gitman
Two corrections, not necessarily pertinent to the question. I wrote: "Thrift
or *SOAP* or ProtoBuf." I meant: "Thrift or *REST* or ProtoBuf." And
about credentials being sent message-level as opposed to transport-level,
well, they always are. I was thinking about the broader question of
message-level vs. transport-level security, and the SSL (where client is
trusting server) is doing the latter.
Building on what Dennis wrote…
I like to look at two-way SSL authentication by breaking it up into two
1. The client trusting the server--to create the secure connection so
the client can pass its credentials.
2. The server authenticating the client.
Here's what I can recall from having to support and document this sort
of thing before in an SOA ecosystem. As Dennis writes, each JVM client is
going to have to pull the server's public key certificate into its keystore.
Then each client is going to have to create their own public/private key
pair using some authority the server trusts and then share the signed
public key certificate with the server. The server will have a persistence
store with its entire known universe of clients and their signed
certificates from which it can authenticate requests. I've done this with
SOAP, so the client would pass their credentials message-level (as opposed
to transport-level) in the header of the SOAP message according to the
WS-Security standard. I'm glossing over so much. Recalling everything that
had to be documented, this is a classic case of "the devil's in the
details."
And not that I'm saying this is a reason in itself to use SOAP. The
client could always pass its one-way hashed public key the way it would
pass a one-way hashed password via Thrift or SOAP or ProtoBuf using some
parameters the client and server agree to; I don't know of any established
practices for those lightweight protocols. I recently saw someone propose
taking a REST JSON message and break it up into a standard envelope
containing a header and a payload, just like you'd do with SOAP, and
frankly, I don't quite know yet what to make of that.
One other observation, and maybe this is stating the obvious. Once you
get to #2, you have a lot of choices how to get the client to authenticate
itself to the server.
Stan Dyck
2013-10-08 21:35:00 UTC
Permalink
Has anyone set up and used mutual authentication SSL with client certificates (preferably with Glassfish, but any setup
would do) and would be willing to give me some pointers ?
I've been looking online for documentation and/or examples, but so far have not found anything concrete or complete
enough to get it working.
Ultimately I would like to use this for programmatic access to web services (or at least considering doing that), but I
thought first step would be to get it to work with a browser. No love.
Any tips would be appreciated.
Hi Linus,

One strategy I've used with success is to configure an instance of apache httpd to handle the authentication and
management of certificates and then use mod_proxy to pass authenticated requests to an underlying application server
like glassfish. There is loads of documentation on configuring client certs for apache out there and it allows you to
decouple authentication issues from application issues.

StanD.


------------------------------------
Jason Osgood
2013-10-09 15:13:44 UTC
Permalink
Hi Linus!
but I thought first step would be to get it to work with a browser.
Using a browser to inspect, verify web services is crucial.

Every browser handles things differently. I managed to attach client certs to Firefox, but not Chrome (?) and Safari. A coworker got IE to work too; I'm told "it just worked". It should be easy to do, once I got one browser working, I ran with it.

First step, I'd follow Dennis' excellent advice and get a small Java client working. With the SSL debugging turned out, that's the easiest way I've found to troubleshoot certificate stuff. Because the browsers are useless for this.

I've mostly been using been Firefox plugin Poster. Meh. I also use SOAP UI to read wsdl and generate empty Requests (to use as templates). I also found a great HTTP POST client for Chrome (I think Stan recommended it, I can dig up the name).


Cheers, Jason

Continue reading on narkive:
Loading...