10

I'm writing a software which is divided into two separate stand-alone pieces. One is a service like application that handles all the logics, the other one is a GUI application that just works as a front-end and is aimed to be used by the end user. The service would listen to a port and accept requests from the client (GUI) application.

Since some sensitive information is exchanged between the service and the GUI applications, they need to be encrypted before getting transferred. One way to secure data is to use a key based encryption but keys need to be stored somewhere on the disk or even in the application's source code, but would rather avoid using keys.

How can I handle a secure connection between service and GUI application without using a key-based encryption algorithm?

Gilles 'SO- stop being evil'
  • 51,415
  • 13
  • 121
  • 180
sepisoad
  • 213
  • 2
  • 7
  • Question [cross-posted](http://programmers.stackexchange.com/q/274644/40065) to Programmers. – Basile Starynkevitch Feb 27 '15 at 08:28
  • by "on the same system" do you mean on the same network or on the same computer/machine? – JPCosta Feb 27 '15 at 11:53
  • on the same computer/machine using tcp socket – sepisoad Feb 27 '15 at 15:47
  • What is your threat model? Who are you trying to protect the system against? – Xander Feb 27 '15 at 17:00
  • @Xander My main concern is that if the GUI and service Apps talk to each other over raw TCP socket (on the same machine) a third party App may intercept the conversation or just listen to the line and copy the sensitive data – sepisoad Feb 28 '15 at 11:41
  • sepisoad - please do not cross post in future. If you think a question is on the wrong site, ask a mod to migrate it for you. – Rory Alsop Mar 02 '15 at 11:24

3 Answers3

16

These are the golden rule of computer security: "It is impossible to hide anything from a competent user with system administrator privilege" and "any competent user with physical access to the device can always elevate himself to system administrator".

You cannot hide any information from someone with physical control of the machine. If the secret you are trying to hide is really important, then you should never transfer the data to the machine and do your processing elsewhere in a place that you control.

Your program is running on a user's machine. You cannot protect your data from the user. With that in mind, does this mean we're doomed? Not necessarily. The operating system provides a wealth of mechanism for programs to communicate privately with another program that will not allow another unprivileged application to intercept it. So, while you cannot protect any data from the user themselves, you can protect your data from another unprivileged program. Providing security boundary between unprivileged programs is one of the main job of the operating systems.

The simplest of this is an anonymous pipe. A pipe allow a unidirectional stream of data to be transported between program. Anonymous pipe is available in Windows, Linux, OSX, and all Unix-like systems. Anonymous pipe most commonly recognized as a pair of pipe called stdin and stdout that allows a parent process to send and receive a stream of data to and from its children. Anonymous pipe can only be used between processes that have parent and child relationship. There is also a named pipe, but they behave differently in Windows and in Linux/Unix-like systems, we will get back to this later.

Another IPC that are commonly available is sockets. Sockets is like a bidirectional pipe. There are many different sockets but they work similarly. The most commonly known is TCP socket. TCP socket is primarily intended for networking between machines but you can also create a loopback TCP socket which can only be used within the same machine. A loopback socket provides privacy (only the program the program that connects and the program that listens can read the data passing through the socket), however it does not really provide mechanism to restrict who can be the other side of the socket.

Another type of socket available in Unix for communication between processes in the same machine is Unix Domain Socket. A Unix domain socket is exposed to programs as a "special file" in the filesystem, and unix filesystem permission is used to control access to the socket. A domain socket cannot be connected to by programs that does not have the right access permission to access the socket file. In Unix-like systems, this means that your service and GUI should run as the same user and/or group that are reserved only for your program and you set the socket file permission appropriately.

Let's get back to named pipe. In Linux/Unix-like systems, a named pipe is pretty much like stdin/stdout in that they are unidirectional. In Windows, however, a named pipe is actually bidirectional and is pretty much the equivalent of Unix domain socket in Windows. Like a lot of things in Windows, named pipe is secured with ACL.

With iOS things becomes a bit hairy. A non-jailbroken iOS only allows a very limited set of inter-process communication, and neither will give you a socket. But if we play loose with definition, in the iOS application, the service program and the GUI program is probably going to actually be the same application, and thus you can simply create a stream directly between different components of the application. This is also secure as the stream is accessible only within the application.

Android provides more options for IPC, including the ability to create domain socket. The API is different but they are conceptually similar with regular Linux. Alternatively, you may go the same approach like in iOS and package your service and GUI in the same application and just use in-process streams.

Lie Ryan
  • 31,279
  • 6
  • 69
  • 93
  • thanks for the comprehensive answer, I may end up changing my design, maybe I put the service code into a shared library. but what I really hate about shared it, is the fact that each platform imposes its own set of constraints and policies so that calling a simple c routine from java(android) or objc(ios) will become a big headache for the developer. – sepisoad Feb 27 '15 at 20:18
  • Well, just as an attempt to "solve" the headache you've mentioned you may create a hybrid application which has a shared codebase, i.e. phonegap, xamarin, etc. which generally have some mechanism of plugins (phonegap, ionic) while the plugin has separate code for each target platform but shares the same API calls. Then creation of a relevant plugin with support for each target platform removes the headache you've mentioned from the end-developer. A bit tricky but may do the job. – Lentyai Jan 29 '19 at 16:02
3

I assume you are the only root/administrator on the machine.

You can use one of those two options:

  1. Do not allow other users on that machine at all
  2. Let the process run as a special user and use a communication mechanism that is only accessible (read + write) to that user (named pipe, unix domain socket, etc.)

Any of those two options will make it unnecessary to encrypt your data on transit.

Note: If there is another (sufficiently skilled) administrator on the machine, you cannot hide anything (including encryption keys) at all.

fex
  • 31
  • 3
  • named pipes or unix domain socket make the process of porting source code to other platforms like windows and ios almost impossible. I need to keep the service code portable however the gui app can be written using platform specific libraries. the communication policy (protocol) is set by the service app and gui app will follow after all – sepisoad Feb 27 '15 at 15:47
  • 1
    You are right about portability. Maybe you can wrap the system API calls so that you can replace it on other systems with secure alternatives (if there are any). Nevertheless, my answer might help some *nix developer who comes across this question... – fex Feb 28 '15 at 21:22
0

Basically, security is usually bear by the key, not the algorithm. So you're on a fool's errand here. As stated by the Kerckhoff's principle: "A cryptosystem should be secure even if everything about the system, except the key, is public knowledge.", or as Shannon reformulated it : "the enemy knows the system". So you can't really have a cryptosystem that do not uses a key in some form and is trully secured.

Since you mentioned in your taglist, let me remind you how this work in principle.

The idea of SSL/TLS (https) is to negotiate a symmetric encryption key to be use for a session of communication between a client and a server. The client connects to the server and asks for its public key (asymmetric cryptography). The key comes as part of a certificates, which can be validated using the chain of certification of the certificate. With that public key and a proper validation of the certificate, the client knows to whom it's talking. So he can safely transmit information.

The client can then use the public key to negotiate a symmetric key to talk to each other for this session. The key cannot be derived for anyone outside the communication (please refer to more detailed explanations if necessary https://security.stackexchange.com/a/20833/1574)

With the use of TLS, confidentiality is ensured between the two partners and the client also can authenticate the server using the chain of certification. If there are needs to authenticate the clients, TLS also support clients certificate.

M'vy
  • 13,053
  • 3
  • 48
  • 69
  • maybe I asked my question poorly, since Enlgish is not my main language, however I will not use any form of key based solutions and will avoid key servers, I just need a solution to secure the exchanged information between two parties – sepisoad Feb 27 '15 at 09:27
  • 2
    You should probably take a look at: http://en.wikipedia.org/wiki/Kerckhoffs%27s_principle . What is said is that you can't rely on secrecy of the algorithm, and that for proper security you are required to have a key. – M'vy Feb 27 '15 at 09:35