Apache Thrift - How to provide secure communication - sockets

I want to secure the communication between Thrift server and client instances. To achieve that, firstly I enabled SSL communication using keystore on the server-side and truststore on the client-side as explained in this post: https://chamibuddhika.wordpress.com/2011/10/03/securing-a-thrift-service/
Afterwards, I wrapped my transport instances on both client and server with TEncryptedFramedTransport.java class provided in the following SO post: Symmetric encryption (AES) in Apache Thrift. This enabled symmetric encryption of messages transferred through socket connection.
My question is that does applying both of these make my communication more secure? Or is it unnecessary to apply both and should go with only one of these?

There is a concept called "defense in depth". The idea is that you still have one more defense in place even when one might got broken. The downside is, as always, that you have to pay for it with performance.
The real question here is this: Do I trust SSL/TLS alone or do I absolutely want to add another (application-)level of security that serves as another hurdle if some man-in-the-middle manages to get inside my SSL/TLS channel, even if that will cost me some performance?
Another aspect could be that might be forced to communicate across unsecure channels, i.e. when there is no TLS available. Remember, Thrift allows to switch transports as needed, and the SSL/TLS infrastructure is only available in certain cases.
If the answer is yes, do it. It would be the same answer with REST, SOAP, XMLRPC, Avro, gRPC or the well-known avian carriers.
So the final, decisive answer if you should do that depends on your priorities.
Be also aware that there could also be other attack vectors in your solution that might need to be adressed.

Related

Best practice for secureing an existing socket connection, without SSL

In Best practice for secure socket connection, the OP wants to secure the connection between two sockets, without SSL.
Thomas Pornin suggests SSH is the answer.
Is this answer based on SSH port forwarding of existing sockets, or just switching to SSH in general?
If not, and the question was how to make existing sockets more secure without SSL, what is the best way to to do that?
If a client on port 10 connects to a server on port 20, how can the server restrict access so that only client on port 10 can connect? And that it really is the client on port 10 (not an imposter)? (Availability only for an authenticated client).
The answer there is any form of the SSH protocol, which is based on channels. You can use those channels to transmit fairly arbitrary information, including port-forwarded data or terminal sessions, or anything you can turn into a byte stream. That said, TLS is generally much easier to implement in code because the libraries are ubiquitous and designed to be used this way. SSH is easier to implement in scripts on Unix-like systems because it has a powerful command-line API.
In most cases, TLS is the better choice. Unless you have a very specialized problem, TLS is almost always the better choice. So the question here is, what problem do you have that TLS doesn't work for? If it's "I hate TLS" then sure, SSH. But TLS is better in most cases.
TLS authenticates using client certificates. SSH authenticates using your private key. In either case, the cert/key is stored in a file that the client reads and uses to authenticate to the server.
It's not clear from your question what you mean by "client" or "imposter" here. Anything that has access to the cert/key will be authorized (possibly requiring a user-provided password), so those must be protected. If when you say "client" you mean "my application," that is not a solvable problem. You can authenticate people. You can to some extent authenticate machines (particularly if you have an HSM or similar piece of security hardware available). You can weakly authenticate that client is claiming to be on port 10, but this is generally useless and extremely fragile, so I wouldn't pursue it. You cannot authenticate software over the network in any meaningful way.
Short answer, though, is to use TLS unless you have a very specialized problem and a good security expert to help you design another solution (and your security expert will almost certainly say "use TLS").

Is it a good idea to use One-time-passwords for securing REST-Applications?

In the last weeks I started building REST-Producing/Consuming web applications and therefore started to worry about the security of my communication.
I made up the following procedure:
One REST-Consumer and one REST-Producer secretly negotiate a common secret and initialize a One-Time-Password(OTP)-Component with this secret.
With every Request and Response the Clients send an OTP.
This OTP is generated by the OTP-Component based on the negotiated secret.
The other partner generates the same order of OTPs and checks whether the sent OTP is correct and accepts or blocks the communication.
After the OTP chain runs empty, the two communicators exchange a new secret and reinitialize (1.).
This structure is generally effective for multi-client environments and communication with many REST-Communicators. I have several questions regarding this procedure:
Is the calculation of OTPs fast enough to handle ms-transactions on the clients?
Is the overhead of the OTPs comparatively small in contrast to other security-features?
Is a OTP-procedure more secure than TLS-communication?
Could OTP-security be a method to use over HTTP-channels? (Assuming, it's ok that the data is plain readable!)
Which security-implementations are as secure as the explained procedure, but are cheaper, faster or less error-prone?
Thanks in advance. Please correct me, if the question has any mistakes or is out-of-scope!
Ok, I've read your question more thoroughly and understood it now. :-)
If you are pre-generating a list of OTPs on both sides there should
be no problem regarding performance. However you need to secure the
storage of the OTPs, which could be tricky regarding who has access
to the systems.
The overhead is IMHO insignificant when you are pregenerating the
list.
TLS is transportlayer security, OTP applicationlayer so there is no
direct comparability. TLS < 1.2 may be unsecure, but so are OTPs if
the way to generate them is weak. Which brings me to the next point:
If you send the OTPs unencrypted it may be possible to do a
man-in-the-middle and reengineer the algorithm and predict the next
OTPs.
Less error prone as in means of already used in production would be
for example Jax-RS secured with CXF. Cheaper? Could be, depends
on the implementation of the OTPs (buy, make, etc.) Faster? No. As
stated in answers to 1 and 2: If you have pre-generated OTPs there's not much overhead.
Regardless of the answers above: You should always think twice before implementing a custom solution in this area, as mistakes can be crucial. Think about the threats to your communication, do a trade-off-analysis and look at the result. Perhaps you will be satisfied using TLS > 1.2?

Does Openfire Support TLS Over Http-Bind? If not whats the alternative

I apologize in advance for the somewhat long windedness of this question but I feel that I need to provide some additional information in order to properly qualify my current predicament.
Background
Okay so in many ways this question is a follow up to a previous question I asked regarding TLS/SSL encryption for XMPP communication and which libraries were the best. At first I resigned myself to using only .net libraries that used TLS/SSL but have since expanded to include Java libraries as also being a suitable alternative and have attempted a simple implementation of the Smack API as well. After exhaustive (and largely misguided) research regarding TLS/SSL encryption I realized that when Openfire is properly configured to block non-secure connections, most XMPP clients when connecting to Openfire will simply auto-negotiated TLS encrypted communications and that as long as I controlled the user roster on the server side (i.e. disable users abilities to create new accounts from any client) that I could more or less create secure end-to-end XMPP collaboration through Openfire.
The New Problem
Once I got the previous issues settled, I attempted to use this method for secure communication over HTTP-binding via Openfire's HTTP-binding functionality and ports. The reason for this is because our implementation will require users to connect to our Openfire server from additional networks. Additionally, and perhaps obviously, we will have no control over how these users firewalls will be configured to allow outgoing socket connections over port 5222 and whats more due to the nature of the system we are implementing it is highly unlikely that any of our clients will be willing/allowed to open their firewall to establish a socket connection to our XMPP server.
The issue is due to the fact that Openfire's Http-Bind does not appear to support auto TLS and instead only supports (as Openfire puts it) the 'Old SSL' method of encryption. This and other Openfire Socket vs Http are discussed in another question here, although not yet at great length
The Question (Finally)
First, can anyone confirm that
Http-Bind through Openfire actually
does not support auto TLS?
Second, does the Smack API support
Http-Bind? There is an existing
ticket on Ignite realtime's
website that seems to state that it
is not supported however the ticket
was created in 2007 and its last
comment from June 2011 that asks if
any update has been made on this
feature has as of yet gone
unanswered.
Third, it seems as though my last
resort to achieve secure
communication using Openfire and
Http-bind would be to use the 'Old
SSL' method however this does not
seem like a good long term solution.
Also, the Openfire forums and other
various rumor mills have indicated
that SSL functionality will be
deprecated in future Openfire
releases (can anyone give credence to
this rumor). All that being said, is
SSL my only real alternative to
secure connection using Http-bind.
By default, Openfire opens two ports for HTTP-Binding (BOSH) based connectivity. One is a plain-text port (7080), one is a TLS/SSL-encrypted port (7483). This is much like the two ports used for regular socket connections (5222,5223).
Clients connecting over the non-HTTP, regular socket port (5222) can elevating the initially plain-text channels to encrypted channels (using STARTTLS). When STARTTLS was introduced (back in ... well, I didn't have kids then) the pre-existing, TLS/SSL-encrypted port (5223) got referred to as the 'old' way of doing encryption. Somewhat overzealous perhaps, some suggestions were made to drop the 'old' technique in favor of the 'new' one.
STARTTLS has not been explicitly added to the 'plain text' port (7080) of the HTTP Binding (BOSH) implementation. This is by design. Unlike the 'plain socket' connectivity on port 5222, BOSH makes use of a transport protocol: HTTP. Channel encryption for BOSH should be completed at the HTTP (transport) layer (port 7483), not the XMPP (application) layer (that translates back to the 'old' way of doing things in the non-HTTP based world of things). This is not Openfire-specific, by the way: it's specified by the BOSH protocol.
As for the deprecation of the 'old' SSL based ports: the general consensus (between Openfire developers) is that there's no point in removing the 'old' SSL port: although the technique is somewhat outdated, it's not less secure than the more modern (STARTTLS) technique. On top of that, the discussion to drop 'old' SSL ports is oriented towards the non-HTTP based connectivity (socket connections for clients, server-to-server, external components, etc). And finally, the discussion is somewhat distorted by a similar yet distinct discussion on whether to change the default port numbering for BOSH (Openfire usage of 7080/7483 predates the definition of standard BOSH port numbering).
As, by design, the BOSH implementation is intended to utilize HTTP-provided encryption, its encrypted port will continue to exist.
As for the Smack-supporting-BOSH question: Smack supports that: https://www.igniterealtime.org/builds/smack/docs/latest/javadoc/org/jivesoftware/smack/bosh/XMPPBOSHConnection.html

How does zeromq work together with SSL?

I am considerung to use zeromq as messaging layer between my applications. At least in some cases I want the communication to be secure and I am thinking about SSL.
Is there some standard way how to ssl-enable zeromq? As far as I understand it doesn't support it out of the box.
It would be nice if I just had a parameter when connnecting to a socket (bool: useSsl) :)
Any ideas?
Understanding that this is not really an answer to your question, I'm going to be encrypting the messages directly with RSA, before sending them with 0mq.
In the absence of a more integrated encryption method that is fully tested and implemented in my platform of choice, that's what I'm going with. 0mq just recently released version 4, which has encryption baked in, but it's still considered experimental and isn't fully supported by the language bindings.
Encrypting the message, rather than the connection, seems to provide the simplest upgrade path, and the difference for our purposes are pretty much just semantics given how we'd have to implement encryption currently, today.
Edit: I know more about encryption now than I did when I wrote this, RSA is not an appropriate choice for encrypting message data. Use AES, either with manually sharing keys (this is our approach for the short term) or implementing a key sharing scheme as in Jim Miller's answer... but beware if you take the latter approach, designing and implementing a key-sharing scheme securely is hard. Way harder than you'd think. You can implement SSL/TLS directly (using message BIOs), and others have done so, it's also not simple but at least know that the SSL scheme is industry standard and therefore meets a minimum security requirement.
In short, before the Elliptic Curve crypto baked into ZMQ 4 is considered reliable and becomes standard, the "accepted solution" would be to implement SSL/TLS over the connection manually, and failing that, use AES 128 or 256 with a secure key sharing mechanism (key sharing is where RSA would appropriately be used).
We are currently implementing a pre-shared key solution using 0mq that implements a key exchange protocol based loosely on TLS/SSL.
Essentially, we have a data aggregator service that publishes encrypted state of health data over a multicast 0mq publisher. A symmetric key is used (AES128) to encrypt the data and can be retrieved from a second service running as a simpler request/response model over 0mq.
To retrieve the symmetric key (PSK), we are implementing the following protocol:
Client connects
Server sends its certificate
Client verifies server certificate against a CA chain of trust
Client sends its certificate
Server verifies client certificate against its CA chain
Server encrypts PSK using client public key
Server sends encrypted PSK to client
Client decrypts PSK
Once a client has the PSK, it can decrypt the messages retrieved over multicast.
We are also looking at implementing a session expire algorithm that uses two enveloped keys in the multicast service. One key is the current session key, and the second is the old, expiring key. That way, a client has a little more time to retrieve the new key without having to buffer encrypted messages before retrieving the new key.
According to zeromq.org, it's not supported yet but they are looking into it. It looks like it's suggested as a project for Google Summer of Code.

Implementing a Handshake for a Socket Connection

I'm developing a program with a client/server model where the client logs on to the server, and the server assigns a session id/handshake which the client will use to identify/authorize its subsequent messages to the server.
I'm wondering what length should the handshake be for it to be reasonably secure but also short enough to minimize data overhead, since I'd like to have it be low latency.
I'm thinking of using MD5 or murmurhash2 with the username and a random number salt with a collision detection, but I'm wondering if there's a more efficient solution (i.e. a better algorithm) and whether 32bits is too much/too little for this kind of thing.
Any input is highly appreciated.
I would use a HTTPS connection for your client/server communications.
It's easy to use (almost all the major SDKs implement it) and it provides good encription.
Regards.
PD: In reference of encryption method I would use Whirlpool because Mr. Rivest said in 2005 it was broken.
This may not be as simple as it looks. Note that if you send anything in clear over the network (e.g. session id/handshake), anyone can eavesdrop the communication and reuse this value to act as the client.
If you cannot use https, as the first answer suggested, you probably need to look at key agreement protocols. Once both parties agree on a shared secret key (which cannot be reconstructed based on observed communications), you can use it to authenticate all the remaining transmissions with a MAC (e.g. HMAC).
Whatever you do, don't use MD5, it's so totally broken. Whirlpool may also not be the good option, it's slower and there is a recent (theoretical) attack on the main part of it, see
ASIACRYPT 2009 Program.
I would stick with SHA-256 for now.