0

I have a web based application for a network that needs to be able to run without internet access. I have wanted to add TLS to protect certain data in transport. I have explored options like Lets Encrypt and OpenSSL but neither seem truly viable for my situation. Lets Encrypt requires internet access and OpenSSL requires you to add an additional trusted CA to client machines. For many of the environments this app could run, robust TLS may be overkill but I would still like to protect some information in transport. I had an idea to accomplish this. I am hoping those here can explain why this solution may not be recommended and if an existing solution may be more desirable.

So lets say I have a login form where TLS is not available. To prevent a valid user's credentials from being observable when sent to the server I would do the following:

  • When serving the page first generate a high entropy random token and relate this token to the un-validated session ID.
  • When the user submits their credentials, first encrypt the values on the client using the token as a key.
  • When the credentials arrive at the server the server will find the associated key for this session ID.
  • Once we have a possible key we will then decrypt the login credential and test against those that are valid.
  • Whether this login is successful or not, if this key is valid it will be destroyed.
  • A successful login will destroy the key and generate a new session ID while invalidating the previous ID.

Please explain to me why this solution may not be recommended and some possible weak points. DOS attacks are not of large concern.

  • 1
    What's to stop the passive observer from observing the random token sent from the server to the client in step 1, then observing the encrypted credentials sent from the client to the server in step 2, then using the random token observed in step 1 to decrypt the payload sent in step 2? – mti2935 Apr 20 '20 at 21:48

2 Answers2

2

It looks for me that you try to invent your own security solution not because the existing solutions don't work but only because you don't understand how the existing solutions work. In other words: don't roll your own crypto.

In detail:

Lets Encrypt requires internet access and OpenSSL requires you to add an additional trusted CA to client machines.

You are comparing apples and apple trees. Let's Encrypt is a CA which can be used to issue certificates. OpenSSL is a library which implements TLS and also can be used to create your own certificates.

... robust TLS may be overkill but I would still like to protect some information in transport.

You feel that TLS may be overkill but don't explain why. If it is about certificates - TLS can be used without these, i.e. it can work with a pre shared key too.

... When serving the page first generate a high entropy random token and relate this token to the un-validated session ID. ...

Basically the server creates a secret which is later used by the client - i.e. a shared secret. Only the client cannot even be sure that the secret is created by the server since it can be created by a man in the middle. Without proper authentication of the server the client does not know who it is communicating with, it might be the server but it might also be an attacker. In TLS certificates or pre shared keys provide this authentication you are missing.

Thus basically you just assume that the first connection will be to the real server. This is called TOFU - Trust On First Use. It can be achieved with TLS too: the server might have some certificate the client has never seen before but the client will trust it once and later check that the same certificate is used for all following connections.

A successful login will destroy the key and generate a new session ID while invalidating the previous ID.

Only it is not really TOFU since the clients seems to forget the server as soon as it logged in and will hopefully connect to the proper server and not some attacker for the next login too - but that's just hoping since the client will not actually check.

Please explain to me why this solution may not be recommended ...

The main problem with this is that you don't have enough understanding of established methods so that you think that established methods don't work in your case. Again, don't roll your own crypto but instead use established ones were lots of experts worked on it.

Steffen Ullrich
  • 190,458
  • 29
  • 381
  • 434
1

Steffen's answer covers most of it, as usual.

Some points:

Lets Encrypt requires internet access and OpenSSL requires you to add an additional trusted CA to client machines.

More or less. Lets Encrypt requires internet access to generate a certificate you will install on a webserver. After you generated the certificate, you can use it offline on a browser because LetsEncrypt CA certificate is trusted by the browser.

OpenSSL does not require you to add the CA on the trusted store. Depending on your application, you can generate a server certificate using OpenSSL, import the certificate only in the application, and you are done. Every time your client needs to talk to the server, it will encrypt all data using this stored certificate. No need to install the CA on the client.

The issue with all your idea is that the client has no idea who is he talking to: he cannot authenticate the server. So the security of everything depends on nobody executing a MitM attack against the client, and in this case, your encryption is as good as plaintext. I explain.

If you send data as plaintext, any attacker between the client and the server can read all data in plaintext, and that's not good. So you generate a token server-side, and send it to client, and the client encrypts the data using this token. Any attacker between the client and the server can change the response and add its own token, decrypt data from the client, inspect/change/store, and send it to the server. Encryption does not prevent anything.

Your application looks like a Web application. You can use sjcl for client-side crypto IF you can safely deliver the server certificate to the client. And safely means that the certificate is signed by a trusted CA, or hard-coded on the application and delivered without the possibility of a MitM attack.

ThoriumBR
  • 51,983
  • 13
  • 131
  • 149