0

I am writing a client/server TCP program and wish to encrypt and authenticate the connection using TLS. My plan was for clients to submit public RSA keys to the server and then use the private key and a username both to authenticate the client's identity and encrypt the connection.

The GnuTLS documentation leaves a lot to be desired, but I found a good PSK example and tried to adapt it to use RSA asymmetrical keys. After banging my head against this problem, in particular all sorts of obscure subtleties which are not clearly described by the documentation, I have got the client to stop complaining about "No supported cipher suites have been found" but now the server does.

After yet more searching of the internet I found a test program that is part of GnuTLS CI that tests RSA-PSK and I realised that the shared key is still symmetrical. RSA-PSK is not what I thought it was.

I really don't like using a symmetrical key as it needs to be stored in plain on the server side and is thus insecure.

However a brief look at RSA key exchange suggests that there is no username involved and it is actually certificate based, and that the server uses its own private key while all clients use the same public key. Thus it is impossible to guarantee a client's identity.

After spending a day trying to get TLS to work, and being loathe to re-invent the wheel (which is always a security risk) I am asking here in case there are any experts who can advise me on how to achieve what I am seeking to achieve.

The only solution that springs to mind is rather dirty and hacky (and reinventing the wheel), namely to implement a pre-TLS-handshake handshake where the client generates a random key, encrypts it with its private key, and sends it and the username to the server which then uses the public key to decrypt it. GnuTLS can then use normal symmetric PSK key exchange using the random key.

I don't understand why GnuTLS doesn't implement something like this anyway. What I was expecting was for the GnuTLS client to send the username to the server, the server then performs key exchange by generating keys for the encryption and encrypts them using the client's public key and sends the encrypted key to the client. The client decrypts the key using its private key and lo and behold, key exchange is securely complete and the TLS channel is open.

So in summary:

1) How do I achieve what I need to achieve (preferably using GnuTLS)?

2) Why doesn't RSA-PSK work as I expect and instead use symmetric keys and a certificate?

AlastairG
  • 4,119
  • 5
  • 26
  • 41
  • After reading this a couple of times I still have no idea what you're trying to do. Maybe we can start with the basics: what's wrong with good old standard server-authenticated TLS? – President James K. Polk Oct 12 '17 at 13:47
  • I need to authenticate the client, not the server. If an attacker spoofs the server they achieve nothing. What I am trying to achieve is more like an SSH connection where only certain clients can connect and they need to be able to prove their identity. I want authentication to be by public key. This is all covered in the first paragraph. I also want to avoid the complexity of certificate signing chains. – AlastairG Oct 13 '17 at 08:09
  • I also want to encrypt the data connection. I don't want to use PSK because it is symmetric encryption. If our database is compromised the attacker can access our system (although if they can grab the database they can probably do all sort sof other things as well, but still). SRP looks dodgy - there is no real explanation of how it is secure. Whether you send the password or the mangled password for key exchange purposes, it still looks like it is sent in the clear. – AlastairG Oct 13 '17 at 08:11
  • I just bumped into something called libssh2 - maybe I should have used that instead, but I'm quite a long way down the path of using libgcrypt at the moment. – AlastairG Oct 13 '17 at 08:19

1 Answers1

0

TLS is unsuitable for the purpose to which I was trying to put it. Libssh would probably be the best solution but I have already finished a full solution using libgcrypt, so...

AlastairG
  • 4,119
  • 5
  • 26
  • 41