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/
Related
I have a java client which communicates with python server. Both run within out company intranet. None are exposed to Internet. How I am supposed to ensure that communication happens over SSL?
I have read a lot online and I have come up with following conclusions:
I will generate primary key and certificate to be used by clients and server using java keytool. (creating keystore, private key, certificate and truststore,extracting private key from keystore)
Using private key and certificate inside my python server using SSLSocket class as explained here
Using certificate in truststore inside java client as explained here
I have some doubts:
Are above steps ok?
Above seems to be one way SSL. Should I be doing two way SSL?
Should I be creating shared secret key and communicating using it?
I know this is something related to requirements. But I am in doubt as I am doing SSL first time.
SSL certificates requires validation via (HTTP/HTTPS), I suggest you enable HTTP/HTTPS for the location IP on the router/firewall to allow the validation to go through the internet.
If that is not possible, then you might have to do some local-server SSL validation. By generating a "SELF SIGNED" certificate and registering it manually in both locations.
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 trying to improve some code that enables logging in to our application using digital certificates, probably certificates stored on PKCS11 tokens.
It's a Java client server application, with the server on JBoss [Wildfly], and a rich Java thick client. We also have a GWT/Javascript based web client, but this doesn't yet support certificate auth.
The current implementation uses 2-way SSL authentication if certificate authentication is configured, i.e. the server will require a client certificate when the connection is opened. This causes some problems, and in trying to find ways to address them I've been searching madly to see if there is a standard, 'Right Way To Do PKI Auth To A JBoss Application'.
However just about everything I have found on the subject seems also to revolve around using two-way SSL, which kind of implies that is the Right Way to Do It.
It seems undesirable to me, in that the network transport is quite a low-level concern, heavily separated from the application logic and stuff like authentication and user management.
In order to prove the client is a valid user of the system (as opposed to merely someone with credentials endorsed by a CA in the server trust store), the server application logic has to rummage around looking to find the certificate that was used on the incoming connection in order to scrape the Common Name off it. I've discovered that javax.servlet.request.X509Certificate is a standard-ish parameter one can query on the servlet, so it ought at least to be possible.
The other architectural problem this causes is that our app requires reauthentication for the lifetime of certain sensitive operations. If one is using the SSL connection to prove the user has the private key, then logically that would require opening a whole separate connection.
Logically, authenticating with a certificate would seem to require
The server generating a nonce
The client encrypting the nonce using the client's private key
The client sending that encrypted value to the server with the accompanying public certificate [or certificate chain].
Now, that is exactly what happens during an SSL handshake, but obviously a whole load of other baggage comes with it that is irrelevant to the application-level concern of authenticating the user.
I thought about implementing the steps directly myself, but this would seem to violate the first rule of crypto (Don't implement your own crypto).
If the server generates random nonces then that introduces a level of chattiness and statefulness to the process, which is doable but a pain when you are striving for a stateless and clusterable server.
Time-based One-Time Password implementations circumvent this, and seem to be a standardized mechanism for 2-factor authentication that is getting support from Google+ and the like.
However I can't find anything in the way of out-of-the-box libraries that will let me build an implementation using certificates directly from an imposed PKI.
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).
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