Nate, all
reading your questions I understand that your use case is
that many clients send communicate with a service. Ok so far?
Each client has its own certificate, the requests shall be
signed and encrypted. The responses also signed and
encrypted.
Well, to keep the effort of the certificate adminsitration
low I usually use the following technique. Using this way
no special programmin on the client or service is required,
all handled via standard deployment.
Client part, request:
- set up the client to use Binary Security Token (BST) when
signing:
<parameter name="signatureKeyIdentifier" value="DirectReference" />
In this way the request contains the client's
certificate, i.e. its public key. Because the certificate
is included in the request the server does not need to store
the certificate of every client.
- Use the server's certificate (the public key) to perform
request encryption.
Server part, request:
- The handler (WSDoAllReceiver/WSSecurityEngine)) extracts the client's
certificate from the request (because it's a Binary Security Token).
Use this certificate to verfiy and perform trust verification agains
the root certificate (certificate of the Certificate Authority, CA).
The current verifyTrust implemetation requires to have all client
certificates in the keystore to provide a better security/trust
check against phony DNs and possible other mismatches.
- the handler stores the extracted client certificate in the message
context. This is transparent to the client and server code.
Server part, response:
- To perform signing the server uses its private key to sign. You may
use BST or some other way to identify the server's certificate.
Every client needs to have the server's certificate anyway if you
encrypt the request (see above).
- To perform response encryption set the encryption user name to
"useReqSigCert". This is a special name that directs the WSDoAllSender
handler to use the stored client's certificate (the clients public key)
to perform response encryption.
Client part, response:
- nothing special, just set up the response stream correctly in the
client's WSDD file.
As pointed out, usually no modification in client/service coding
necessary, also no need to change the trust handling inside
WSDoAllReceiver except that you need a very special certificate
trust verification.
Note: while looking at the verifyTrust implementation I saw some
code that I don't really understand (or is buggy). Probably we
have to dig into it to check it.
Regards,
Werner
> -----Urspr�ngliche Nachricht-----
> Von: Ruchith Fernando [mailto:[EMAIL PROTECTED]
> Gesendet: Donnerstag, 2. Juni 2005 16:42
> An: Nathaniel A. Johnson
> Cc: [email protected]
> Betreff: Re: AW: encryption not asking for the right private key
>
>
> Hi Nate,
>
> The client's public key is stored in the message context (in the
> receiver results - WSHandlerConstants.RECV_RESULTS - and retrieved
> later to encrypt the out going message (by the WSDoAllSender).
>
> WSDoAllSender - private void handleSpecialUser(RequestData reqData)
>
> Therefore if the client sending the incoming message uses a trusted
> cert then the out going message will be encrypted with that cert.
>
> But there's Trust verification part that happens at the service (by
> the WSDoAllReceiver -
> verifyTrust(X509Certificate cert, RequestData reqData) throws
> AxisFault
>
> This requires the client cert to be in the keystore of the service. I
> guess you can change this ONLY IF you want to trust all the requests
> AND if you don't have each client's cert with you.
>
> Best regards,
> Ruchith
>
> On 6/2/05, Nathaniel A. Johnson <[EMAIL PROTECTED]> wrote:
> > -----BEGIN PGP SIGNED MESSAGE-----
> > Hash: SHA1
> >
> > Hello again Werner,
> >
> > So I fixed my encryption problem. I totally read the documentation
> > wrong. I just needed to supply the encryptionUser in the
> wsdd, which
> > makes perfect sense in hindsight :) Thanks for getting me
> thinking :)
> >
> > New Related Problem:
> >
> > This works great for request flows from the client to the
> web service
> > since there is only one service the client is talking to (multiple
> > clients talk to this service) and the client can just
> insert the service
> > as the encryptionUser. And it works for responses from the
> service to
> > the client when I hardcode the client as the encryptionUser in the
> > server.wsdd like follows:
> >
> > <responseFlow>
> > <handler type="java:org.apache.ws.axis.security.WSDoAllSender" >
> > <parameter name="user" value="groupsserver"/>
> > <parameter name="passwordCallbackClass"
> > value="edu.iu.uis.osg.security.PWCallback"/>
> > <parameter name="encryptionUser" value="xxappclient"/>
> > <parameter name="action" value="Signature Encrypt"/>
> > <parameter name="signaturePropFile"
> > value="server-crypto.properties" />
> > <parameter name="signatureKeyIdentifier"
> value="DirectReference" />
> > <parameter name="encryptionKeyIdentifier"
> > value="X509KeyIdentifier" />
> > </handler>
> > </responseFlow>
> >
> > But there are many clients, so is there some way for my server to
> > determine who is calling it and encrypt the response back
> to it with the
> > correct public key?
> >
> > Thanks yet again!
> > Nate
> >
> >
> >
> > Nathaniel A. Johnson wrote:
> > > Hi Werner,
> > >
> > > Your description of signatures and encryption with key pairs makes
> > > perfect sense. It did get me thinking of something I
> figured was just
> > > happening behind the scenes somewhere, which is that the
> client "just
> > > knew" to use the server's public key to do the
> encrypting. Is there
> > > some config setting, property file or what not, that
> should be set so
> > > that the client know's to use the server's public key to
> encrypt with?
> > > In the client.wsdd there are signaturePropFile and possibly
> > > encryptionPropFile and decryptionPropFile properties, but
> those files
> > > all have passwords in them, so I can't allow the client to see the
> > > server files, right?
> > >
> > > I must just be missing where I tell the client what to use for
> > > encryption... any help would be great!
> > >
> > > Thanks!
> > > Nate
> > >
> > > PS: Signatures are working great for me, both in the request and
> > > response flows of the service, so I at least have half of
> it working :)
> > >
> > >
> > > Dittmann Werner wrote:
> > >
> > >>>Nate,
> > >>>
> > >>>both the Client and the Server use the Merlin calls to access
> > >>>the keystore and to deal with certificates.
> > >>>
> > >>>If you do Signature the the client needs _its_ private
> > >>>key to sign, the server needs the client's public key
> > >>>to verify.
> > >>>
> > >>>If you encrypt then the client uses the _server's
> > >>>public_ key to encrypt the symmetric session key, the
> > >>>server uses _its_ private key to decrypt the session
> > >>>key. Thus, the case you are describing is probably
> > >>>a problem in the deployment - if you use Encryption
> > >>>the you must use the server's certificate to do so
> > >>>(the certificate contains the public key). To me it
> > >>>seems that you specified the client's certificate to do
> > >>>encryption.
> > >>>
> > >>>Regards,
> > >>>Werner
> > >>>
> > >>>
> > >>>
> > >>>>-----Urspr�ngliche Nachricht-----
> > >>>>Von: Nathaniel A. Johnson [mailto:[EMAIL PROTECTED]
> > >>>>Gesendet: Mittwoch, 1. Juni 2005 16:54
> > >>>>An: [email protected]
> > >>>>Betreff: encryption not asking for the right private key
> > >>>>
> > >>>>
> > >>>>hi all,
> > >>>>
> > >>>>i just posted this over on the axis list, but realized
> its probably
> > >>>>better suited for the wss4j dev list... sorry for the
> cross post for
> > >>>>those of you that are on both lists...
> > >>>>
> > >>>>i have been stepping through the axis and wss4j code
> and am at a loss.
> > >>>>here is the code it is getting to (inside Merlin.java):
> > >>>>
> > >>>>public PrivateKey getPrivateKey(String alias, String password)
> > >>>> throws Exception {
> > >>>> if (alias == null) {
> > >>>> throw new Exception("alias is null");
> > >>>> }
> > >>>> boolean b = keystore.isKeyEntry(alias);
> > >>>> if (!b) {
> > >>>> log.error("Cannot find key for alias: " + alias);
> > >>>> throw new Exception("Cannot find key for alias: " + alias);
> > >>>> }
> > >>>> Key keyTmp = keystore.getKey(alias, password.toCharArray());
> > >>>> if (!(keyTmp instanceof PrivateKey)) {
> > >>>> throw new Exception("Key is not a private key,
> alias: " + alias);
> > >>>> }
> > >>>> return (PrivateKey) keyTmp;
> > >>>>}
> > >>>>
> > >>>>this is when the client calls to the service. the client is
> > >>>>sending an
> > >>>>encrypted/signed message. what's happening is the server
> > >>>>(web service)
> > >>>>is trying to get the private key for the client. that just
> > >>>>doesnt make
> > >>>>sense. the server will not have a keyEntry (private
> key) for the
> > >>>>client, just public keys.
> > >>>>
> > >>>>does anyone have any idea where i might be going wrong?
> i have been
> > >>>>looking at this problem for over a week now, so maybe i am
> > >>>>just missing
> > >>>>something? i feel like i am going crazy.
> > >>>>
> > >>>>thanks
> > >>>>nate
> > >
> > -----BEGIN PGP SIGNATURE-----
> > Version: GnuPG v1.4.0 (MingW32)
> >
> > iD8DBQFCnxXIgj8ksIjnb2wRAuyXAKCYKpnsdF9MSEnWWJQq2nKRzDEddQCbBtdc
> > iRdDluLBfm0Zrp5v8HvpnaY=
> > =Ha5n
> > -----END PGP SIGNATURE-----
> >
>