In case of webapplicaiton I can understand that there is no difference between the client authentication and user authenticaiton; Ignoring XSS and other exploits the web client is generated by the server/servlet.
But suppose you have a Java client application talking to the Java Server application; The server has a certificate associated with it so that the client can validate and verify if server is trusted. Now client also has a certificate (client cert) so that the server can verify if this is a trusted client; Once this mutual authentication is done, instead of presenting a username/password dialog to the user, the users certificate (user cert) can be passed to the server.
Question is whether there is any advantage/use in this case in having a (client cert); Or will the user certificate alone will suffice to trust the client as well ??
I know this is an obvious question/ but cant a rouge client application be created ?? So will the client cert protect against this scenario.
Any time you have a client server application the server needs to assume the client is compromised. When an authentication occurs (username/password, certificate, etc... it doesn't matter) the server should grant the user certain permissions to use the functionality of the server. Whenever a request is made to the server the server needs to check whether the authenticated user has the permission to perform that action.
Trusting the client to only make authorized requests opens yourself up to attacks. If you check permissions on the server and scrub inputs then you don't have to worry about whether the user is using a trusted client because even an untrusted client won't be able to do more than the trusted client could with the same authentication credentials.
These principles apply regardless of wether you are using a web client or a stand alone client. Even in a web app I can write a new client and POST data, use RESTful services, or generally talk to the web server and completely bypass the web ui you present to me.
If some attacker gets to alter in some way the client application, it could use the valid user certification to access the server.
The server should verify the client app, not for server sake (we assume the server checks if client can do this or that operation, but for ensuring the client is not being phished by a bogus client). Then the server can proclaim that all operations made by client-1 we're made through some verified client-app (agent) so they were really intended by the user.
The client application's certificate (and it's private key) can be easily ripped off the application and rogue application can be created. The ways to counteract this are (a) use user's certificate and let the user provide it when needed and (b) use a USB cryptotoken to store the client certificate and it's private key. Cryptotokens don't let the private keys out so the attacker can't copy it (though he can use the token with his application, if he has physical access to the token).
Related
actually we want to authenticate user depends on client certificate.
here is the process,
We will issue a client certificate for each device.(it will be a selfSign certificate)
We would like to enable Server with client certificate authentication.
only users who attempt to connect from clients loaded with the right client certificates will succeed.
Even if a legitimate user attempts to connect with the right username and password,
if that user isn't on a client application loaded with the right client certificate,
that user will not be granted access.
We would like to identify\authenticate each device\user with a unqiue certificate.
This feature doesn’t appear to be supported by App Engine. There is currently a request filed for this feature to allow authentication with App Engine using SSL certificates based on user device and you can view updates here.
I've generated classes from wsdl with wsimport, wsdl location: https://somehost/wsdl. There was no problem with generation.
But when I tried to send soap request, I've received exception:
com.sun.xml.internal.ws.client.ClientTransportException: The server sent HTTP status code 403: Client certificate required
I find out, surfing the internet, that I have to add certificate in my keystore. I've done it, but this doesn't help.
And I have no idea what to do or even what to google.
Can anybody help me?(
It sounds like a mutual authentication problem.
The server is requiring that your client use a known digital certificate to sign your messages and send that information within the request. It is like a user/password mechanism, but you and the server agree to use a known key-pair for identification.
This situation usually means that the web service server administrator will generate a key-pair and send the private part of the certificate to you.
But you can send the public certificate for him as well if you created it yourself. The server must have access to the public certificate, and it maybe you will have to publish it to a Certification Authority. In some cases it has to be a commercial certificate (you will have to buy it).
You will then use the private key to digitally sign your messages.
I've found some links that may help:
Authentication Mechanisms
Java client for the X.509 secured web-service
Java HTTPS client certificate authentication
If you already did those steps, then something is wrong with your implementation or the certificate/keys provided are invalid.
I recommend you to use a mock server to make sure you are implementing the client authentication properly before you try to connect to the real service. Making it to work locally will set the knowledge you need to call the real functions. You can also ask the web service administrator to send you debug information.
I've got users authenticating with client certificates in a JBoss server. All fine.
If I then use Apache HTTPClient to call onto another server it sends the client certificate of the user JBoss is configured with. I'd like to be able to pass the client certificate through so the second server authenticates the calling user too.
Is this possible (I'm assuming not as the server won't have the private key of the client certificate) and if so, how?
I'm pretty convinced from RFC5246 [1] that it's not possible.
If the client has sent
a certificate with signing ability, a digitally-signed
CertificateVerify message is sent to explicitly verify possession of
the private key in the certificate.
After all, what's the point of a private key if you make it public? I'll just get the server I'm connecting to to give my system user increased privileges.
1 https://www.rfc-editor.org/rfc/rfc5246
Not possible. The certificate is merely a public identifier of who the user is. The actual authentication is done using the client's private key. As a result, you would need to obtain both the certificate AND private key to accomplish this, which would eliminate all of the security around the use of certificates in the first place. Certificates are considered public, and can be distributed wherever needed to allow for identity verification, digital signature validation, encryption, etc. The private key must, by definition, remain private in order to ensure the security of the credential.
To accomplish your goal of propagating identity information, there are other tools you can use. If your JBoss server(s) are all part of the same security domain, you can use JavaEE Security to propagate the identity information. With some creative coding, you may also be able to use Kerberos to propagate the identity, although that is a non-trivial amount of effort.
I have a server application and a client application created with java that will communicate with the server application. But, since i haven't put emphasis on security in the server side it is really easy to hack the server application if a hacker creates his own client to connect with my server. I want to make sure the client application that is communicating with my server is the authentic client that i created. I upload client to a specific host like www.abcd.com. Now, can i make sure when a client that connects to my server came from that host. I am knowledgeable about signing it with trusted signer but i am looking for a cheap option.
No, this isn't possible. If it were, DRM would work, but everyone knows it's hopelessly broken.
To be truly secure, the client has to be a machine with a "trusted platform module," TPM, that supports something called remote attestation. This allows the server to verify the client is authentic and unaltered. But I've never heard of a real world application of this, and though TPMs are common, I'm not sure if the remote attestation feature is.
I want to make sure the client application that is communicating with my server is the authentic client that i created.
You have two options. One is a password or shared secret, and the other is client certificates. All three are supported in SSL/TLS. Look for TLS-SRP (password based authenticated key exchange), TLS_PSK (preshared key based on a block cipher), and the traditional SSLTLS ciphers with client side certificates.
You can even set up the tunnel with Server Authentication only, and then perform the client authentication at the application level. This is what usually happens in web apps. But this has some non-trivial defects because it does not provide mutual authentication and lacks channel binding. You are better off with TLS-SRP, TLS-PSK, or client certificates.
EDIT: I focused on SSL/TLS because you cited a hostname, but you can do it at other layers, too. For example, you can use shared secrets and certificates at the VPN level. #erickson provides one method using TPMs that could be used at the application level.
Now, can i make sure when a client that connects to my server came from that host.... host like www.abcd.com
This will work if DNS is configured and trustworthy. That is, you will have to extract the host's name, perform a reverse lookup, and then authenticate the IP address. I believe this is called network based authentication.
If an attacker controls DNS or is on the same LAN segment as the server, then I believe network based authentication has some non-trivial security defects.
In any case, HSMs and TPMs are not the answer. To understand why, see Peter Gutmann's Engineering Security, and the section on Unattended Key Storage. From his book:
TPMs don’t work because all that they can do is store the fixed key
that’s required to decrypt the other keys (TPMs are just repurposed
smart cards and don’t have the horsepower to perform anything more
than lightweight crypto themselves so you can’t offload the overall
encryption processing to them), and since for unattended operation
they have to release their secrets without a PIN being entered they’re
just providing plaintext key storage with one level of indirection.
I am writing an application that should ensure secured connection between two parties (call them Client and Server).
Server should restrict which clients can connect using https. For this purpose, server will issue a certain number of certificates that will be checked when a client tries to connect. If the certificate that the client is using is not in trusted list, connection would not be established.
This certificate should be distributed using some kind of usb device. So when Client using my application tries to get something from server using https, application should read that certificate from usb device and USE IT to establish https connection. Private key should be kept secret on the device at all times.
So far I managed to create local keystores on client and server (JKS), add them to each other trusted list and use them to achieve proper connection.
My question is: can client certificates be issued by a server and transported to clients, all together with private key required for https connection? I dont want any data or keystore to be created on the client machine, everything required for establishing https connection should be on that device. Device could have some procedures and api to help this process and ensure secrecy of private key.
Any help will be greatly appreciated :)
can client certificates be issued by a server and transported to
clients, all together with private key required for https connection?
Technically, they can, but you're going to have to authenticate that connection by some other means if you want to make sure that private key only gets to its intended user. As far as your overall scheme is concerned, this doesn't really help. In addition by sending the private key as data to the client, they may be able to extract it one way or another.
If you can physically send a USB device, you can use a hardware cryptographic token that supports PKCS#11. Such tokens tend to have options to store a private key in a way in can't be extracted (it can only be used with the device). They tend to come in to forms: as a smart card (in which case you need a reader) or as a USB token (it looks like a memory stick, but it's not). Depending on the model, the USB token can in fact be a smart card with an embedded reader.
Java supports PKCS#11 keystores, so if this token comes with a PKCS#11 driver/library, it could be used from Java.
The normal client certificate approach to authentication doesn't work well if you don't trust the client to protect their credentials - which seems to be your scenario.
Putting the certificate on the USB device keeps it off the client machine's disk, but doesn't stop the client user from accessing it and distributing it to others. On the other hand, it reduces the risk of 3rd parties stealing the certificate from the client machine "at rest" - but only if the client protects the USB key properly. So you need to be clear about what threats you are trying to defend against, and who you trust.
The only way to make the certificate at all 'private' from the client user is to put it on some kind of tamper-resistant device, and use an approach that does not transmit the certificate to the client machine during authentication.
Compare your approach with those used for internet banking, where the customer is issued a device that can do challenge-response, using their bank card and PIN (two-factor authentication). The card details are protected from casual attack by the card's chip; but the system assumes that the client looks after their card and PIN, and reports thefts promptly (because it's their money at risk!). If the client is not motivated to look after the credentials, then this approach does not make sense.
If you just want to ensure that the client has an unsharable token, you could consider using SecurID devices, or similar, which are an off-the-shelf solution to your problem.