I would like to implement tls protocol on my server and client.
My question is simple:
the class SSLSocket use either the TLS protocol or is it the same thing?
I haven't implemented it in my code yet, but I'm excited about the possibility.
My question is simple: the class SSLSocket use either the TLS protocol or is it the same thing?
The short answer is Yes.
The standard SSLSocket class supports both SSL and TLS. Quoting from the first line of the javadoc:
"This class extends Sockets and provides secure socket using protocols such as the "Secure Sockets Layer" (SSL) or IETF "Transport Layer Security" (TLS) protocols."
However this need to be qualified in that the actual protocols and versions that are allowed depend on defaults and settings that change over time. For example, recent Java releases will (by default) reject SSLv2, SSLv3, TLSv1, and TLSv1.1.
Finally, you should avoid using any of the disabled versions (or related disabled features) if possible as they have known security weaknesses and in some cases are vulnerable to compromise.
Related
I'm working with a framework (Vertx 2) and need to implement a service that runs on top of TLS. Vertx 2 has support for TLS, but I cannot get it to use the necessary ciphers (among others):
TLS_PSK_WITH_3DES_EDE_CBC_SHA
TLS_PSK_WITH_AES_128_CBC_SHA
I also cannot use the Bouncy Castle lightweight API as it is stream-based and blocks (spawning threads etc. to deal with this is not acceptable as that will not scale). The same goes for JESSIE.
It must use AES & DES with pre-shared keys, but I've been unable to find a way to get this to work. Any solution which is non-blocking/async is workable.
If you're on Linux or OSX, Conscrypt (https://conscrypt.org) might be an option. This is an OpenSSL/BoringSSL backed JCA Provider which will give you an SSLEngine impl which you can then use with Java NIO in non-blocking mode. For context, Conscrypt is the default provider of crypto and TLS/SSL primitives on Android.
To use it with TLS-PSK, you'll need to initialize a Conscrypt-provided SSLContext with an implementation of org.conscrypt.PSKKeyManager and then obtain an SSLEngine from that context. For documentation, see PSKKeyManager interface Javadoc or Javadoc of very similar Android framework class PskKeyManager (https://developer.android.com/reference/android/net/PskKeyManager.html).
I'm developing secure communication framework for PC and Android mobiles, without using certificates and public key exchange. Pre-shared key will be used.
The framework has it's own protocol for authentication and key exchange.
The procedure is the follows:
Hosts authenticate to each other
After two communicating hosts are authenticated to each other, they share session private key.
Traffic between hosts is encrypted using that key.
I plan to use SSL for traffic encryption, but without using and third-party SSL library (only standard JSSE facilities).
Actually, SSL will be used only for traffic encryption (key exchange and authentication is already made).
How it's possible to explicitly set pre-shared key for SSL?
If it's not directly supported by JSSE, but can be made by overriding default SSL classes (SSLEngine, SSLSocketFactory, and etc), how to do it? What classes can be responsible for it?
SSL/TLS lets you use several mechanisms for authentication besides certificates, eg. you can use shared secret (PSK cipher suites) or OpenPGP keys and more. However, not many implementations actually support those mechanisms. I don't know whether Java built-in cryptography supports them. Our SecureBlackbox does support all mechanisms defined in TLS specifications including those I've mentioned.
You can find open source TLS PSK JSSE socket factories powered by Bouncy Castle and released under the Apache v2 license here: https://github.com/clover/pskfactories
The project includes example usage.
Alternatively WolfSSL also appears to have a JSSE implementation that supports PSK. It's powered by native code so likely a bit more work to get up and running than if it was pure Java. It's also GPLv2 unless you purchase a commercial license.
See https://www.wolfssl.com/products/wolfssl-jni-jsse/
I'm trying to tunnel tls via a text-only communication channel (I thought about using base64) but I cannot seem to find a tls server example that doesn't use SSLSocket.
For a tls client I was able to find the bouncy castle TlsProtocolHandler which is transport agnostic because it just uses an input and output stream, but I couldn't find anything similar for a server tls implementation.
Using SSLSocket:
You can certainly implement your own Socket that is not based on TCP. For example there are Unix socket implementations. Once you have it for your own transport, SSLSocketFactory.createSocket(Socket, ...) can establish an SSLSocket on top of your own Socket.
Using SSLEngine (a bit more complex):
SSLEngine.wrap (and unwrap) work on ByteBuffers. These buffers could come from your own communication channel.
One of the difficulties you may encounter is the mapping of the notion of certificates to your custom transport. Certificates (or more generally proving the identity of the server) is essential to the security of an SSL/TLS channel, to prevent MITM attacks. Identity verification requires both checking the certificate as trusted, and that the identity it's for corresponds to the entity you were trying to reach (hostname verification). Hostname verification isn't enabled by default, but you'd need to find something similar anyway, if you don't have host names (that could be a problem for unix sockets, for example, although using SSL in this case might not make sense anyway).
There is a project that uses extensively JSSE.
Depending on a configuration parameter the SSLContext is initialized for SSLv3. Meaning that if the parameter is not set it is SSLv3, otherwise it is TLS.
I noticed some handshake failures occasionally and traced it: If the client negotiated TLS and the server replied with SSLv3, the handshake failed
Why does this happen? I thought that TLS and SSLv3 are pretty much interchangeable.
Are they not? If I change server side to always reply TLS is there a chance I will break something?
TLS 1.0 is, internally, SSL 3.1. A client and a server may accept to use either or both; during the handshake, the client sends the highest protocol version it knows of, and the server should select the highest version that it supports that is not always newer than the one sent by the client.
My guess is that when you configure your client to use TLS, then the client understands it as "use only TLS 1.0": the client sends "3.1", and if the server is configured to respond with "3.0", then the client will quite logically reject the connection.
What you should do is find a way to configure the server to accept both 3.0 and 3.1, and thus use whatever protocol version was announced by the client. Alternatively, configure the client to declare that it knows 3.1, but such that it also accepts a "downgrade" to 3.0 if the server says so.
You don't say what you are trying to achieve by varying the protocol parameter. SSLv3 and TLS1.0 are very similar but nevertheless distinct protocols. The protocol negotiation mechanism introduced in SSLv3 is also used in subsequent protocols. The bottom line is that in SSLContext.getInstance("proto"); you should set proto to the earliest version of the SSL protocol you are willing to support. After that, the peers will negotiate to use the newest version of the protocol they both support.
I have the following question on SSL/TLS.
After the server hello, starts the authentication phase of the server.
From various articles/books, it appears that this phase is optional. E.g. in wiki
The server sends its Certificate
message (depending on the selected
cipher suite, this may be omitted by
the server).
But I do not understand what it means to say that it depends on the encryption suite.
So my understanding is either a ServerKeyExchange or a Certificate follows a ServerHello.
So my question is, can the server authentication be omitted all together?
For example to omit client aunthentication in Tomcat, you just configure the connector to not request it.
How can the server authentication be omitted? Does it depend on the java framework I use, if it supports it?
And what does it mean to omit the server authentication? If the certificate is not send then the ServerKeyExchange becomes mandatory, or usually frameworks allow provisioning of a local public key instead if one wants to by pass-authentication phase for performance or because it does not make any sense?
Or does this depends on the encryption suite somehow, as wiki seems to imply?
NOTE:
I understand that server should always be authenticated. The context of my problem though is a client app and server running on the same machine (and java runtime I guess) so it can be considered safe to bypass server authentication (I think).
Any input is highly welcome!
Thanks!
In TLS/SSL, server authentication is optional.
If you choose TLS/SSL cipher suite without authn (such as TLS_NULL_WITH_NULL_NULL (turns off authn and encryption) or TLS_DH_anon_XXXX (use only encryption) in TLS specification), server certificate won't be sent.
TLS/SSL without authn doesn't seem to be supported pure-Java connector.
But I think the native-connector with SSLCipherSuite=aNULL supports it.
I don't know it's safe to disable authn, i.e., attacks such as DNS-spoofing might be threats.
I think you'd better to use server authn if performance is not problem.
Or, turning off TLS/SSL itself might be choice. (Encrypting server-client communication might be meaningless because administrator of the computer can steal certificate files and dump JVM heap.)
Authentication and Encryption are important when data travels across an untrusted network or when one of the endpoints is not trusted. If you application only makes connections on localhost, then Authentication and Encryption aren't important (the fact that your data and application are on locahost implies a trust in localhost).
you can get ssl configuration for tomcat 6 from
http://nayanmali.blogspot.com/
you got whole configuration and how to create keytool and how to generate certificate form that