Android HttpsUrlConnection with multiple client certificates + connection pooling? - java

In my application, I verify a the Android user's identity by giving each user a different client-side SSL certificate. I'd like to use HttpsUrlConnection to connect to the server since that's Google's recommended way.
The user can switch accounts (log out from the current one and log in with a different account). In this scenario, I need to estabilish the HTTPS connections with the new user account's client-side cert.
How will HttpsUrlConnection's connection pooling mechanism work in this environment? How can I force all HTTPS connections in the connection pool using the wrong client-side cert to disconnect?

With the, err, disconnect() method.

Related

Jetty client / server mutual authentication

I am trying to build a client / server servlet application with these general requisites:
both the client and the server are jetty embedded;
the server expose a servlet in order to receive json data via POST;
the connection must be secured via SSL (i.e. the connection will be done via Internet via https);
I want that only my Jetty client be able to send data to my server, all other tentative must be refused by the server;
the server and the client are unattended machines (i.e. not password via command line could be inserted by human);
no password in clear must be stored on the client device. In general I don't want someone could open the remote client device and stole the password and building a fake remote device capable to send data to my server too.
I have build a perfectly working client / server application via HTTP but I am confused about the security.
I have read that there is the possibility to use client / server mutual authentication and seems what I am looking for but I can't get the complete picture.
In this document client-certificate-authentication there is a more or less clear explanation about how to build a shared trusted CA but the password for accessing the TrustStore and the KeyStore are in clear in the code.
I think I am missing a tile in the puzzle.
Could someone point me in the right direction?
Thanks,
S.
I'm going with a simple answer (for now).
If you just want only your clients to talk to the server, then yes, Client SSL/TLS certificates are the way to go.
You'll want the server's SslContextFactory.Server.setNeedClientAuth(true) set to true. That will in turn cause Java's javax.net.ssl.SSLParameters.setNeedClientAuth(true) to be set on incoming connection establishment. If the client fails to provide the client certificate, the connection is closed, and no HTTP request is sent or processed.
As for securing the client certificate, that's up to you, you can do anything you want to do, as long as it results in a valid client SslContextFactory.Client that the Jetty client can access. This includes ...
Using plaintext passwords
Using obfuscated passwords (minimal effort, minimal security)
Encrypted keystore/truststore passwords elsewhere in your client, provided to the SslContextFactory.Client at the last minute. (modest security, wouldn't be that hard to figure out)
Creating the java.security.KeyStore object yourself and handing it to SslContextFactory.Client.setKeyStore(KeyStore) and SslContextFactory.Client.setTrustStore(KeyStore) methods prior to starting the Jetty Client. (a bit better security wise, puts more work on your behalf)
You might want to consider having the client certificates be short-lived (24 hours?) dynamically refreshed from the server, and have the client certificates be revokable (at the server/CA side) if you encounter abuse. (such as the same client certificate from multiple different client IPs)

JDBC connection over internet without ssl

Is JDBC connection to a remote database over the internet without SSL but authentication with username and password enabled is insecure ? Is attack like man in the middle possible for such scenarios ?
Authentication NOT implies confidentiality. SSL/TLS was born to grant the latter. So you have to use a secured connection. But I'd suggest you to not expose you DB to the Internet. Use a microservices-like pattern to isolate the DB from unwanted exposures.
It is insecure, never expose your database on internet, not even using ssl. If you really need to do so, make a ssh tunnel or configure a vpn.

Is there a way to dynamically trigger SSL/TLS renegotiation in a servlet?

I want to be able to accept both web browser clients and (automated) service clients to a single servlet running in my application. Some of the service clients will authenticate with TLS client certificates, but some will not. I do not want web browser clients to be prompted for a certificate ever, even if the user has some installed in their browser. The decision on whether to prompt for a client certificate is dynamic and based on policy according to the client, so cannot be statically configured in web.xml.
Is there a way to dynamically trigger TLS renegotiation to request a client certificate from within a servlet? If I had access to the raw SSLSocket then I could configure it to require a client certificate and then call startHandshake() to force renegotiation. As far as I can tell, there is no portable way to get hold of the SSLSocket associated with a servlet request/response though.
My application has to run in a variety of servlet containers, so I'd prefer to avoid container-specific solutions if possible. Ideally the solution would not involve a redirect, but I will accept that if it is the only way.
You wrote in comments above:
because that setting will cause a web browser to prompt the user to
choose a certificate if they have one installed that matches one of
the configured CAs. I never want that to happen for web browser
clients
Then I vote for this is impossible to achieve from server side. TLS takes first before any data sent through secure channel. You can't determine is it web browser or not knocking at your door not asking for client identity. From TLS point of view this is just yet another unnamed network client attempts to connect. After secure connection established, data is sent, and you can determine this is browser or not.
You may want to pipe browsers (1 way ssl) and server client (2 way ssl) through different endpoints.
Otherwise you may want to implement you own TLS protocol handshake procedure.
You may want to configure browsers not to answer to client certificate requests instead of configure server not to ask if (if it would be possible) to determine this is browser-based client. May be try to guess it through the cypher suit (list of supported crypto modes) but this is definitely not servlet level of interaction.
I am curious somebody know ho to solve you question.

How to secure communication in client-server app?

I've got backend running on the tomcat server and client running in the browser. Application is built on Spring 3 MVC + Spring security framework. How to secure the communication ? Is there other option than just to set the server to be accessed only via HTTPS ? I've got no experience with this so it might be a stupid question, but will this affect my application and do I have to set something up in my app, when the server shall communicate with client via GET/POST request via https ?
It depends somewhat what you mean by "secure." If you want privacy, you must use TLS (SSL) as a transport.
If you're only concerned with authentication, then you have another option: Digest Authentication.
Digest Authentication allows the client (browser, usually) and the server to exchange authentication credentials in a secure manner without securing the entire communication. If you use Digest Authentication, then third parties can still:
See what data the client and server exchange
Insert themselves between the client and server and alter the exchange
What third parties cannot do is spoof the authentication or steal username/passwords in transit.
If that's not secure enough, you need TLS. You do not necessarily have to purchase a certificate. You can use OpenSSL to generate your own. This certificate will not automatically be trusted by browsers, however, so you can't really use it for public sites.
You will need to consult your server documentation for how to set up HTTPS or Digest Authentication, depending on which fits your needs.
Your application should not be affected by switching from HTTP to HTTPS, Tomcat handles this or maybe an Apache in front. It's important to understand, that HTTPS is a server-thing, not an application topic, because the client makes a connection to the server (Tomcat), not to your application. Check out the Tomcat documentation, it's pretty clear about how things work.
And, like the others said: From what you've said it's best to use HTTPS (TLS/SSL). Certificates are a bit frightning at the beginning, but it's worth to invest the time.
HTTPS is the (S)ecure form of HTTP, since you have an HTTP client server application I would certainly used HTTPS. All you need is to create an SSL certicate for your website and restrict access to your website to HTTPS only, then you are 99.99% secure.
Your certicate can be either commercial from Versign or equivalent or some open source engine.
for the clients nothing needs to be done to support HTTPS

How does the SQL Server JDBC Trusted Connection Authentication work?

How does the SQL Server JDBC Trusted Connection Authentication work? (ie how does the trusted connection authenticate the logged in AD user in such a transparent and elegant fashion and how can I implement a similar authentication solution for my client-server applications in Java without a database connection or any use of the existing SQL Server solution.)
Assumptions
* Working within a Windows 2003 domain
* You have access to the Windows API via JNI/JNA
It depends on the client. For example if you have a Web Browser, it can use the NTLM Authentication to pass the domain authentication of your current client to the server. In this case the browser like IE or FF supports this, and you web server needs the support for NTLM. For example here for Tomcat: http://jcifs.samba.org/src/docs/ntlmhttpauth.html
There is also the SPNEGO protcol in combination with Kerberos, as explained here: http://java.sun.com/javase/6/docs/technotes/guides/security/jgss/lab/index.html
If you have your own client, it depends on the client's framework if it is able to use the local user's security context and is able to pass it on. The page above describes this at least for a kerberos scenario.
Greetings
Bernd
PS: I am not sure if you can pass the authentication context established with the jcifs/ntmlm solution to a backend component like SQL Server. It should work with Kerberos tickets (if configured).
jTDS and Microsoft JDBC Driver both offer native Windows Authentication.
Have you looked at this question? The situation seems to be similar to yours (connecting to a SQL Server database using Windows authentication).

Categories

Resources