I have a Java app (deployed as a JAR file) that allows file sharing through SLLSockets. If all users use the same certificate, file transfers are not secure, since it violates the core concept of asymmetric encrypted communication. Therefore, I understand that each user needs to have its own certificate. This brings up my first question:
How can you generate a certificate programmatically, and where would you store it ? I don't want users to have to generate their own certificate with keytool, then have to tell the app where it is located.
Now, let's say my first question is answered and each user has its own certificate. Prior to opening the SSL connection between two hosts, you need to add each other's certificate to the trustStore. The only way I know to achieve this is by exchanging them through Sockets (note that I am using JGroups to exchange Socket connection info). This brings up my next two questions:
How do you guarantee authentication and integrity when exchanging the certificates ?
How do you programmatically add the received certificate to the trustStore ?
Finally, this whole post brings up my fourth question:
Are the steps described above the correct way to send data securely between two hosts, using SSLSocket asymmetric encrypted communication ?
You don't need client certificates necessarily.
Could you not use username/password authentication?
You can still secure the transfer just by using a server certificate.
Client certs are also kind of a pain, and not entirely secure. They tie you to a machine, and evil processes can read them. Smart cards mitigate this, but aren't free.
Related
Here is the situation:
Our Application talks to multiple 3rd party applications and few of them need client authentication.
One particular third party app needs client auth and has appropriately provided certificates (which we imported in our key store (JKS)). This is during integration testing. Things are working fine in the Test environment.
Now before going live, they want to upgrade the certificate issued by an CA.
For the new certificate, we can always create a new store, but for the sake
of convenience wanted to know if the two certificates(old and new) can reside in the same store? (So that in case they rollback, there is no change on our side)
URL being same, how does the application(http-client library) knows which client certificate(s) version to present when making calls to server?
You can have both certificates in the truststore. JSSE will select whichever one matches the trusted CAs the server advises when it requests the client certificate.
However the scenario you describe is radically insecure. If you are the client, you should be providing your own client certificate, not one that comes from someone else. Otherwise there must be a compromise of the private key, which means the certificate can't be used for the purpose it is intended for, and you can legally repudiate all transactions that are supposedly authenticated via this means. Client authentication under such a scheme serves no useful purpose whatsoever and you should not waste further time on it.
I'm currently developing an application for Android thay will allow users to back up their data on a server, which I am also developing in Java. I've pretty much completed the development of the features such as file transfer, registering and logging in and so on (mysql database keeping records of users and passwords) and so on. I've come to a halt in my development when trying to implement security features. I want to use asymmetric cryptography for authentication and symmetric cryptography for encrypting communication between client and server. So here is the deal:
The communication between client and server will be doing using AES. This relies on a Preshared key between both parties. This Preshared key will be generated on the client side each time a session is initiated and will be sent to the server, encrypted using the servers public key. That way, only the server that posses the private key will be able to decrypt the Preshared key and read the communication. Where I am a bit confused is the sharing of the servers public key. Now I know the best way to do this is to use a digital certificate containing the servers public key. I also know this certificate should come from a trusted CA.
My question is, how do I go about getting a digital certificate for my server? Will my android application request for this certificate from the server or the CA? My initial thought is that it has to receive this certificate from a CA, as if it receives it from the server, it may be fraudulent. What is the process and the correct way of going about this? Anywhere I read, it just talks about https connection from client to Web server. I am writing a server in java that will communicate over sockets with my android application. How do I go about creating, receiving and verifying certificates in relation to trusted CAs?
Thanks
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about a specific programming problem, a software algorithm, or software tools primarily used by programmers. If you believe the question would be on-topic on another Stack Exchange site, you can leave a comment to explain where the question may be able to be answered.
Closed 8 years ago.
Improve this question
My legacy Application is on https(SSL). On top of that i can see some users are configured to use
digital certificates which are created by my own CA using OpenSSL? With this i have got CAcert.pem and CAkey.pem which
are used to create digital certificates for user who requests for it(thru CSR).
My understanding with this
is that whenever user(using digital certificates) tries to connect to server , browser sends the installed Digital
certificate to server automatically(Question is how browser knows this is digital enabled user and it needs to send the certificate? )
and server validates (Who is responsible to validate the certicate information on server side?)
My last question is How Digital certificates provides extra security on top of SSL?
UPDATE :-
As you said Digital certificates are essential part of ssl not different from it(where digital certificates are sent from server
to client containing the publick key and information about the CA whom browser trusts). Now browser will send the data encrypted
with public key which will be decrypted at server side with private key. Similarly when server send the response it will be
reverse i.e encrypted with public key and decrypted with public key at browser side Right?
Bruno, You are right i actually wanted to get the information about client certificates.
I also got the with client certificate, extra security is provided becoz client is subjected to the same strength of authentication from the server. So even if the password is stolen, but hacker does not have client certificate. he can not proceed.
But i am not sure how it works. I have got some
idea with your answer but still questions i asked in OP still puzzles me. I will tell you my configuration. I am sure you can help me then.
I am using Tomcat webserver. Here is the snippet in server.xml i added
Step1 :-
<Connector
SSLEnabled="true"
acceptCount="100"
connectionTimeout="20000"
executor="tomcatThreadPool"
keystoreFile="c/.keystore"
keystorePass="changeme"
maxKeepAliveRequests="15"
port="443"
protocol="HTTP/1.1"
redirectPort="443"
scheme="https"
secure="true"
/>
Step 2
Added below snippet in tomcat-users.xml file
<role rolename="certrole"/>
<user username="ignoreAndCheckInWebApp" password="nopass" roles="certrole"/>
Step 3
Added below sniipet in web.xml
<security-constraint>
<web-resource-collection>
<web-resource-name>Client Certificate Auth</web-resource-name>
<url-pattern>/MyClientAuthenticator.jsp</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>certrole</role-name>
</auth-constraint>
</security-constraint>
<login-config>
<auth-method>CLIENT-CERT</auth-method>
</login-config>
placed a jar file conatining MySSlAuthentication.java into the lib folder of Tomcat.
Step 4
Then added below valve element under tomcat\conf\context.xml
<Valve className="MySSlAuthentication"/>
So its more or less th eprocedure mentioned at http://twoguysarguing.wordpress.com/2009/11/03/mutual-authentication-with-client-cert-tomcat-6-and-httpclient/ but i am unable to understand the steps(why and when they are required) and how they are linked to each other ?
Now my question is:-
I am not able to relate steps 2,3 and 4. I want to understand what happens when browser tries to connect to MyClientAuthenticator.jsp? My understanding when browser tries to call the MyClientAuthenticator.jsp, server asks the client certificate from browser. But then how/when step 2 and step 4 comes in to picture?
How Digital certificates provides extra security on top of SSL?
In general, I wouldn't say digital certificates provide "extra" security on top of SSL/TLS. Rather, they're an essential part of it. Although the PKI details and how to verify the certificates isn't part of the TLS specification (RFC 5246) (there are a couple of additional specifications for this, such as RFC 5280 and RFC 6125), the specification itself clearly references quite heavily certificates and how they should be used.
You seem to be talking about client certificates, but you probably already know about server certificates, which are far more common.
In both cases, the purpose of certificates in SSL/TLS is to authenticate the communicating parties, so that each party can be sure it's talking with the remote party it expects.
You should always at least have a server certificate (otherwise the connection would be vulnerable to MITM attacks). This proves the identity of the server to the client.
In addition to this, some configurations expect the client to provide a certificate. Since you're talking about users using their certificates from their browser, you seem to be in this situation.
In this case, the extra security is that the client is subjected to the same strength of authentication from the server, as the server is from the client. In particular, since the private key never leaves the remote party in this process, this helps prevents impersonation by password theft (since no password is transmitted). There are more details in this question on Security.SE.
Requesting a client certificate is something that can only be done by the server. If your server is configured to do so, it will send a message to the client (your browser) during the SSL/TLS handshake, and this message will normally contain a list of CA certificates it trusts, to give an indication of which client certificates it is willing to accept. (In this particular case, your server will most likely have been configured to request client certificates issued by your CA.)
Your server will have been coded and configured to do so (I'm not sure from your question whether you're using a Java Servlet container or a bespoke Java server).
The validation of the certificate is done by the trust manager in Java. This is often initialised transparently by providing the application with a trust store and relying on the default behaviour of the default SSLContext (then used by the default SSLSocket or SSLEngine depending on how your application is coded). Assuming your server uses the default trust manager and is configured with a trust store containing your CA certificate (and is also set up to request a certificate), it will send the name of that CA to the browsers than connect to it, and it will also use that CA to verify the certificate then sent by the browser.
(Some applications may also have a customised trust manager, but then its behaviour depends entirely on what it was written to do.)
Java provides two way of requesting a certificate: "need" or "want" (see SSLSocket.setNeedClientAuth(...)). The difference is that with "need", the connection will stop if the client didn't present a user certificate, whereas it will continue in this case with "want".
After this, the server application can check the authentication status of the user by checking the peer certificate from the SSLSession. (It won't get any peer certificate if the client didn't send one and the server used the "want" mode. This may be fine for anonymous access.)
At this stage (provided the server application was coded with the correct trust manager, i.e. not a dummy one), the server code will be ensured that the remote user is indeed the holder of the private key matching that certificate. The Subject Distinguished Name of the certificate can then be used as the identity of the remote party. (Some servers allow you to match this to a different set of user names if necessary. This will depend on which exact server you're using and how it's configured.)
As you said Digital certificates are essential part of ssl not different from it(where digital certificates are sent from server to client containing the publick key and information about the CA whom browser trusts). Now browser will send the data encrypted with public key which will be decrypted at server side with private key. Similarly when server send the response it will be reverse i.e encrypted with public key and decrypted with public key at browser side Right?
No, whether you use client certificates or not, the connection will be encrypted in both directions anyway, using a symmetric key negotiated during the handshake. Client certificate have nothing to do with it. The client certificate is only used to sign the handshake at the end, to prove to the server that the client has the private key for this certificate.
The details in your edit seem to indicate you're using a configuration that's probably a bit more complex than usual.
Firstly, your Connector doesn't have a clientAuth attribute (so its default value is false). This implies that the client certificate will not happen during the initial handshake, but will be triggered by a second handshake when you try to access the protected resource (according to your security-constraint configuration). This is called re-negotiation, and it's not unusual.
(I've also noticed that it doesn't have truststore-related settings, which implies it's using the default JRE truststore, which also implies that your custom CA certificate must have been imported explicitly into that truststore (cacerts in general). Keep this in mind if you upgrade your JRE, since you're probably have to import that cert there manually again.)
Your tomcat-users.xml configuration is what I was talking about earlier (about matching Subject DNs to user names or roles). This, combined with your custom valve is what's unusual in your settings.
My guess would be that this valve maps any valid certificate to a pseudo-user called ignoreAndCheckInWebApp, just to be able to pass that security constraint, although your application would be expected to look at the certificate itself.
In a more traditional case, the usernames in tomcat-users.xml would be the Subject DNs of your certificates, and you would map them to roles this way. Here, it seems your deployment doesn't care about this mapping at that point, but is meant to check this within your application later. This probably means that your application should directly rely on HttpServletRequest.getRemoteUser() (unless it's also set up by a filter later), but should read the certificate using the "javax.servlet.request.X509Certificate" attribute from the request.
This can make sense if the application does all of this correctly. What I'm saying here is really a guess, since it depends entirely on how the Tomcat valve is implemented. This will certainly affect the remote user name and user principals that you get.
Regarding your comments about ActiveX and IE, client-certificate authentication should also work fine with Firefox or Chrome. Two things come to mind:
That ActiveX code may simply have nothing to do with client certificates, but may be part of the what the application is meant to do.
That ActiveX code is part of your own CA, as a means to let your users apply for certificates from within their browsers (when they don't already have one). Perhaps this was only implemented for IE, although it could be done for Firefox or other browsers too.
Question is how browser knows this is digital enabled user and it needs to send the certificate? )
The browser sends it because the server asked for it, because the server is configured to do so.
Who is responsible to validate the certicate information on server side?
The SSL implementation is responsible.
How Digital certificates provides extra security on top of SSL?
As part of SSL, you mean. They securely identify the owner, which gives the application a chance to decide whether that user is authorised to use this part of the application.
Re your UPDATE:
Now browser will send the data encrypted with public key which will be decrypted at server side with private key. Similarly when server send the response it will be reverse i.e encrypted with public key and decrypted with public key at browser side Right?
Wrong. The encryption and decryption processes aren't different just because the client provided a certificate. What really happens is that the client and server negotiate a symmetric session key. Public-private key encryption isn't used.
1)How browser knows when it has to send the client certificate(AS EJP pointed out server asks for it but i am not sure where it is asking it in above configuration).
It is asking for it because of this:
<auth-method>CLIENT-CERT</auth-method>
2)Whoz is validating client certificate at server side ? Is it MySSlAuthentication?
The SSL implementation associated with the Connector validates the client certificate. You haven't told us what MySSlAuthentication is, so I can't tell you what it does.
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.