I've implemented HTTPS connection with servlet running REST api.
Device is able to connect to server using HTTPS.
Device is accepting server's certificate and establishing HTTPS.
How to make sure that the device accepts only a particular certificate? The intention is that someone should not be able to setup a fake server identifying itself as right server using self-signed certificate.
In a browser environment, user would see Chrome's crossed out https in the url and know that the certificate is not verified. How to ensure that for an app.
The procedure is called certificate validation and is pretty standard. Some classes and components perform validation for you, others leave it for your manual implementation and control.
Validation ensures (in ideal world) that you are connecting to the legitimate server, i.e. the server whose host name and the name in the presented certificate match. This requires that the server has acquired a valid CA-signed (we omit self-signed variants for lack of security and flexibility) certificate for the needed host name. So far so good.
Now you can either rely on pre-implemented certificate validation or implement your own or add your own checks to the pre-implemented validation procedure. Implementing your own validation is too cumbersome for your task, so let's assume that the client code you use already performs some validation (you have not specified what exactly code you use for connection so I can't comment on it). You can rely on it, however in some countries state agencies perlustrate traffic, and for doing this they acquire (or generate on-the-fly in some cases) certificates which are fake by nature but valid if we follow the validation procedure blindly.
So if you control both the server and the client and also you can implement additional validation (your client component or class lets you do this) then your additional check can be to compare the issuer of the certificate (or the whole certificate chain) to the issuer you know to be valid. This is less flexible and to some extent against the PKI rules, but this approach significantly reduces the chance for the fake certificate to be generated and accepted as valid. The idea is that you know what certificate you use and what CA you used (and maybe use in future), so you can store this information in the client and compare it during validation.
You can read more about certificate validation by simply searching here on SO for "certificate validation" - this is quite popular topic.
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'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.
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.
My requirement is to secure the REST webservice. After some discussion decided to go with PKI over oauth. The implementation will be in Java.
Now I have the following questions in mind?
If I enable SSL in my web server that just implements PKI infrastructure?
If I implement whatever is mentioned in this guide, that will take care of all encryption and decryption?. How the original messaged passsed between the servers are encrypted/decrypted?. Or this guide just talks about authorizing the client and nothing to do with the message passed?
If my above assumptions are wrong, Can you hep me in understanding, all I need to know about implementing this infrastructure?
Nope, it does not. Public key infrastructure is about the handling of the certificates (holding the public keys) and the private keys. You need to take care of certificate exchange, certificate lifetime, certificate revocation etc. etc. Of course, most of these are taken over by the Certificate Authority like Verizon. Even then, you need to protect and backup the private key you are using, and make sure it fits your server name, and that you update your certificate when it's time runs out.
Yes, the SSL/TLS protocol takes responsability of securing all the messages passed, at "transport level". You may of course require additional security at application level (e.g. to store send messages securily on the server). In general, SSL/TLS would suffice, and the implementation takes care of it all. You should however decide which SSL cipher suites you want to enable.
Um, I would suggest you read articles and books about PKI, and possibly some howto's from CA's. That question (and actually the two other questions) are off topic for stackoverflow. It's impossible to answer that in a few sentences.
PKI (Public Key Infrastructure) deals with certificate life cycle, certificate authority (internal or external), certificate policies and how these certificate can be used.
Enabling SSL / TLS on web server makes secure http connection (https) instead of plain http. By enabling HTTPS, you are securing the data transferred between client and server through encryption.
Note that to enable ssl/tls, you need server certificate and how you obtain the certificate that is take care by this infrastructure. We can configure MS PKI or use openssl tool to generate certificate for in-house purpose, or can buy it from CA's like Verisign, DigiCert etc.
Implementing SSL/TLS will ensure data safety in transit, whereas Authentication & Authorization still needed for end users.
This question may seem like a novice, and perhaps 'stupid' question but please bear with me...
I'm still struggling to find a way to get my Java application to use a keystore located inside the JAR file, and I'm very tempted just to disable certificate validation all together using the method here. However, before I do so, I just wanted to confirm why you should not do this and whether those reasons actually apply to me.
I've heard that no certificate validation can make your application liable to "Man In The Middle" attacks (I think), but even if I am correct, I am unsure as to what these actually are so please could somebody explain. Though, if they are what I think they could be, I'm not sure whether my application ever be subject to them because, my application only uses an SSL connection to obtain data from my website, so users do not tell the application which URLs to visit - if that makes sense...
Here's, an attack scenario. Other's might want to contribute some more.
Your application accesses a URL. At some point along the way (any intermediate network hop), an attacker could position himself as a "man-in-the-middle", that is, he would pretend to be a "proxy" for your communication, being able to read everything that goes through, and even modifying it on the way: the attacker could act on behalf of the user, mislead him as to what information he gets, and basically access al data being transferred.
Enter SSL: your client receives a certificate from the server, with a valid key (Signed by a known certification authority, or present in your keystore). The server will then sign and encrypt all it sends using that key. If an attacker where to place himself in the middle, he would not be able to read the data (it's encrypted) or modify it (it's signed, and modification would break the signature). He could still block communications altogether, but that's another story.
So that's that... if you ignore your keystore, you can't verify any server side certificate, and you open the door to man-in-the-middle attacks.
Though, if they are what I think they could be, I'm not sure whether
my application ever be subject to them because, my application only
uses an SSL connection to obtain data from my website, so users do not
tell the application which URLs to visit - if that makes sense...
If you connect to a server via SSL and you don't do any authentication, effectively you are have no security.
You have no idea who is the endpoint you are talking to.
The fact that the user does not type in a URL, but the URL is a hardcoded URL to your site is irrelevant. A simple proxy that forwards the data from your client to the server can steal all your client's data since there is no kind of authentication (this is the Man in the Middle Attack).
I would suggest you put the code you are using to load the keystore so that you get help on that.
Otherwise, if you don't have any requirements on security and you don't have any sensitive data you should go for plain connection (i.e. non-SSL) so that your performance does not deteriorate due to the unecessary (in your case) SSL overhead