Decrypt stored secret using HTTPS transport - security

I am considering developing a software for safely storing files on a server.
Let's say I have a secret document initially stored on my client computer that I want to upload to the server. The requirements here is that the file on the server should be encrypted at all times and since the private key is on the client, it is unreadable for anyone accessing the server directly. Maybe I can do it with javascript or maybe I need to develop a full fledged app to handle the upload. Either way is OK but I need to be able to download and decrypt the file using web browser only.
This got me thinking. Can I configure HTTPS (SSL) in a way that I can precalculate the encrypted response from server to client. In that case I can do that while uploading and when the document is requested I can just return the pre-encrypted data which will be decrypted by the SSL stack on the client.
I know that the there will be a random number exchange that prevents this. But is there a way to configure SSL so that the response from server to client will be the same always. In this case replay attacks from server to client is acceptable and not an issue.

In an SSL handshake, the client generates the pre-master secret that will be used to derive the session key. Since you appear to have control only over the server, you cannot prevent the client from steering the conversation in a particular (cryptographic) direction.

Related

Should user data be encrypted on the client or server side?

I have a small question to ask you! When a user registers on a site, his password is stored, encrypted, in the database. Encryption is possible in PHP thanks to different functions, notably password_encrypt from memory. In this case, the encryption operates on the server side.
BUT
we can imagine that we encrypt the password in JavaScript, so on the client side, and that we send to the server the already encrypted password!
My question is the following: when the encryption is done on the server side, is there any way to intercept the unencrypted password ON THE SERVER, just before it is encrypted (spy scripts, etc.). In this case, perhaps client-side encryption should be preferred, so if the server is controlled by an attacker, it does not compromise user security.
Also, for the user's trust, isn't client-side encryption better?
What about known sites? Do they encrypt data on the server or client side?
Thank you in advance!

Is it possible to intercept the payload of a secure request in plain text?

Consider we run the following request:
url="https://secretsub.example.com/secretpath/post.php"
payload = {'secretmessage1' : 'foo','secretmessage2' : 'bar'}
r = requests.post(url,data=payload,verify=True)
The language (python) is just arbitrary but it can be a request on any other language (NodeJs, Java, Php...)
Notice that the url is using https, which means that the connection is secured over SSL. Assuming that I compile this program into binary (.exe), would it be possible for computer to read the payloads through a software in plain text?
I know that packet sniffing software (like WireShark), will only reveal the domain name (example.com) in plain text but not the secrepath nor the payload which will be encrypted.
If I run this code in a web browser however (assuming that it is written in Javascript), I will be able to access the payload and the secretpath in plain text inside the browser console. I assume that the browser only encrypts it only after the request is logged in its console. But if this code is run outside the browser, is there a way a for the computer host to intercept those data in plain text? (some sort of packet sniffing tools)
It is only possible to see the domain name, the payload and path are encrypted and can only be decrypted by the session key as negotiated between the client and webserver. But malware on your computer could be able to access it, for instance by having access to the memory used by the application or by using an insecure programming library with some kind of backdoor.
What the https is doing is initiating a certificate exchange so your client will recieve a certificate from the server that validates the server is who thay say they are and allows the client to encrypt the data through the channell (network).
The first bit - validating the server is who they claim to be - relies on something called a certificate chain. The certificate you recieve will have been signed with an issuers private key. Your client should check this certificate using the issuers public key that you should "already have".
Most operating systems have a list of trusted root certificates. In windows you can see them in the certificate manager.
Without knowing python - #Patrick Mevzek hints that you can ship a root CA (certificate authority) or use the OS one. if your using the OS one - you might need to check its going to be there.
I would expect all this to be automatic - its part of the protocol that you've specified i.e. https. However - you might want to confirm that with a python person.
Most people kind of ignore all this bit - but it is very important. If you do not validate the certificate then you are susceptabe to a "Man in the Middle" attack or DNS spoofing.
Basically I can issue a cert for secretsub.example.com using a couple of tools on my desktop. It will not be signed by a valid CA but if you don't check it then I can either place that cert in a proxy (Man in the Middle) - and when you make your requet my proxy will get the real cert from the real server, establish the HTTP connection but issue my cert to your application. You will then encrypt to my proxy with my cert so I can read your data and then forward it to the real server - and you'll never know! (Many corporate proxies do exactly this to their employees).
Alternatively if I can change your DNS to point the IP to my server I can do pretty much the same - act as a proxy.
Once that's done the data will then be encrypted accross the network.
So - yes HTTPS will encrypt accross the network - but check the cert is valid.
Obviously as someone points out - the data is in the clear on the client computer - just like it is in your browser now.
Stuart

Execute and transfer highly secure data between known and unknown hosts

The problem is: I have a script (written in PHP) that is able to get commands, gather and send private data (this is just backup script). Main server will ask scripts to get data.
Now I have 3 security problems I want to solve:
I want to disallow any other server to ask for the private data (no server, except the allowed, can execute any command)
I want to encrypt request - I will send private data in it (for example file names to transfer, which are considered private)
I want to encrypt the response - script will output private data (file contents).
Does anyone has any idea how to achieve these points or has any interesting cases of thoughts in this matter?
My idea is to:
Generate some kind of secure password and encrypt script before I will deploy it to remote server. I store the password and pass it in a request - it will decrypt the script (this is easy in PHP). Remote script then may send request to main server asking was this command authorised. Also, I can check IP of the server.
I will also generate another secure password which is used to encode/decode all sensitive data in request.
The idea here is to use also encode/decode approach from 2, but also not to send a response directly. Script will send request to the server with an answer. (using HTTPS). This will not let data go outside of the connection and will also make sure we use HTTPS (I don't know the status of the remote server, but I'm sure main server has strong SSL).
Is it enough? Will you add anything? WHat are your thougts?
Regards,
Jakub Król.
You can use client certificate authentication. You will generate a certificate for each of your clients, and then your server (i.e. the script you were talking about) will check whether it knows about the given client. See, for example, here for info on using client certificates in PHP.
Since your client knows whom it is sending data to, you can use Asymmetric encryption. Client will use server's public key to encrypt request. Server will decrypt the request with it's private key. Search google/bing for assymetric encryption in php
Similar to point 2), your server may encrypt data for the given client using it's Public key.

Web server that encrypts uploaded files, can withstand compromised server & decrypt to multiple users

There are generally 2 main methods of encrypting user uploaded files.
The client can encrypt the file, send it over for the server to store, and on request the server retrieves the encrypted file and the client does the decryption. In this scenario, the server never has access to the keys. There are cons to this; the encryption scheme is viewable by anyone in the source of the web app, it's extra processing for the client, and others
The second scenario of course is when the client sends the file in plaintext (presumably over SSL), and the server manages the keys and encryption/decryption.
It seems to me that the most common form implemented is the latter, where the server manages the encryption/decryption for the client. This seems ineffectual to me. If the web server is compromised, even if the attacker just has web app level privileges, encryption in the first place was pointless since he will have access to all the keys just as the web app did, and thereby the decrypted files. Is there a way to prevent this? Why would people even encrypt files to begin with then, unless they did client-side encryption and never store the keys?
Also, as a second part to this question, is it feasible to allow multiple people access to an encrypted file (say a division within a company) if you used the former option (client-side encryption)? I would presume the users would have to share their keys among themselves, which poses another security risk.
SSL only protects connection. If you want to prevent server from peeking at yours files, the file must be encrypted by a secret key server does not know. (scenario one)
For the second part, There are many papers discussing how to build such systems based on public key cryptography. Or you may look into other recently crypto reserches, such as broadcast encryption or attribute-based encryption.

Sanity Check: SSL+ POST vs. un-encrypted GET

A classic dumb thing to do is pass something security related info via a GET on the query string ala:
http://foo?SecretFilterUsedForSecurity=username
...any yahoo can just use Fiddler or somesuch to see what's going on....
How safe is it to pass this info to an app server(running SSL) via a POST, however? This link from the Fiddler website seems to indicate one can decrypt HTTPS traffic:
http://fiddler2.com/documentation/Configure-Fiddler/Tasks/DecryptHTTPS
So is this equally dumb if the goal is to make sure the client can't capture / read information you'd prefer them not to? It seems like it is.
Thanks.
Yes, it's "equally dumb". SSL only protects data from being read by a third party; it does not prevent the client (or the server) from reading it. If you do not trust the client to read some data, they should not be given access to that data, even just to make a POST.
Yes, any user can easily examine the data in a POST request, even over HTTPS/SSL, using software like Burp Suite, Webscarab, or Paros Proxy. These proxies will complete the SSL transaction with the server, and then pass on the data to the client. All data passing through the proxy is stored and is visible to the client.
Perhaps you are trying to store sensitive/secret data on the client-side to lighten the load on your server? the way to do this so that the user cannot look at it (or change it) even with a proxy, is to encrypt it with a strong symmetrical secret key known only to the server. If you want to be sure that the encrypted data is not tampered with, throw on an HMAC. Make sure you use a sufficiently random key and a strong encryption algorithm and key length such as AES 256.
If you do this you can offload the storage of this data to the client but still have assurance that it has not changed since the server last saw it, and the client was not able to look at it.
This depends on who you're trying to protect your data from, and how much control you have over the client software. Fundamentally, in any client-server application the client must know what it is sending to the server.
If implemented properly, SSL will prevent any intermediary sniffing or altering the traffic without modifying the client. However, this relies on the connection being encrypted with a valid certificate for the server domain, and on the client refusing to act if this is not the case. Given that condition, the connection can only be decrypted by someone holding the private key for that SSL certificate.
If your "client" is just a web browser, this means that third parties (e.g. at a public wi-fi location) can't intercept the data without alerting the person using the site that something is suspicious. However, it doesn't stop a user deliberately by-passing that prompt in their browser in order to sniff the traffic themselves.
If your client is a custom, binary, application, things are a little safer against "nosy" users: in order to inspect the traffic, they would have to modify the client to by-pass your certificate checks (e.g. by changing the target URL, or tricking the app to trust a forged certificate).
In short, nothing can completely stop a determined user sniffing their own traffic (although you can make it harder) but properly implemented SSL will stop third-parties intercepting traffic.
The other, more important reason not to add confidential information into URL with GET requests is that the web server and any proxies on the way will log it. POST parameters don't get logged by default.
You don't want your passwords to show up in server logs - logs are usually protected much, much less than, for example, the password database itself.

Resources