Why is there a SMTP/HTTP Protocol? I mean, why can't we use (or extend) the existing SSH protocol? Wouldn't using SSH also eliminate the need for a paid key?
Or, perhaps another why to frame this question is why do we need yet another encryption scheme?
There are different protocols for different purposes. What I'm hearing here really is 'why do we need to pay for an SSL certificate in HTTPS but not SSH'.
The reason for this is as follows:
When you first connect to a SSH server, you as the person logging in are asked to validate the public key. Do you read it and recognize the code before you accept it?
Imagine if this were needed the first time you connect to any HTTPS server. We can't ask users to validate every public key manually. How would they recognize what a public key is the correct one?
We solve this by relying on other authorities to validate the keys. These authorities don't just sell SSL certificate, their product really is validating that the person owning the domain is the one encrypting it.
So you can totally generate your own self-signed SSL certificates, but browsers won't recognize these by default. Browsers and operating system have a database of certificates they trust.
Anyway, these days you no longer need to pay for a certificate. LetsEncrypt gives them away for free.
Related
I'm going to be using gRPC for a device to device connection over a network (my device will be running Linux and collecting patient data from various monitors, gRPC will be used by a Windows client system to grab and display that data).
I obviously want to encrypt the data on the wire, but dealing with certificates is going to be a problem for various reasons. I can easily have the server not ask for the client cert, but so far I've been unable to find a way around the client validating the server's cert.
I've got several reasons I don't want to bother with a server cert:
The data collection device (the gRPC server) is going to be assigned an IP and name via DHCP in most cases. Which means that when that name changes (at install time, or when they move the device to a different part of the hospital), I have to automatically fixup the certs. Other than shipping a self-signed CA cert and key with the device, I don't know how to do that.
There are situations where we're going to want to point client to server via IP, not name. Given that gRPC can't do a cert for an IP (https://github.com/grpc/grpc/issues/2691), this becomes a configuration that we can't support without doing something to give a name to a thing we only have an IP for (hosts file on the Windows client?). Given the realities of operating in a hospital IT environment, NOT supporting use of IPs instead of names is NOT an option.
Is there some simple way to accommodate this situation? I'm far from an expert on any of this, so it's entirely possible I've missed something very basic.
Is there some simple way to set the name that the client uses to check the server to be different than the name it uses to connect to the server? That way I could just set a fixed name, use that all the time and be fine.
Is there some way to get a gRPC client to not check the server certificate? (I already have the server setup to ignore the client cert).
Is there some other way to get gRPC to encrypt the connection?
I could conceivably set things up to have the client open an ssh tunnel to the server and then run an insecure gRPC connection across that tunnel, but obviously adding another layer to opening the connection is a pain in the neck, and I'm not at all sure how comfortable the client team is going to be with that.
Thanks for raising this question! Please see my inline replies below:
I obviously want to encrypt the data on the wire, but dealing with
certificates is going to be a problem for various reasons. I can
easily have the server not ask for the client cert, but so far I've
been unable to find a way around the client validating the server's
cert.
There are actually two types of checks happening on the client side: certificate check and the hostname verification check. The former checks the server certificate, to make sure it is trusted by the client; the latter checks the target name with server's identity on the peer certificate. It seems you are suffering with the latter - just want to make sure because you will need to get both of these checks right on the client side, in order to establish a good connection.
The data collection device (the gRPC server) is going to be assigned
an IP and name via DHCP in most cases. Which means that when that name
changes (at install time, or when they move the device to a different
part of the hospital), I have to automatically fixup the certs. Other
than shipping a self-signed CA cert and key with the device, I don't
know how to do that.
There are situations where we're going to want to point client to
server via IP, not name. Given that gRPC can't do a cert for an IP
(https://github.com/grpc/grpc/issues/2691), this becomes a
configuration that we can't support without doing something to give a
name to a thing we only have an IP for (hosts file on the Windows
client?). Given the realities of operating in a hospital IT
environment, NOT supporting use of IPs instead of names is NOT an
option.
gRPC supports IP address(it is also mentioned in the last comment of the issue you brought up). You will have to put your IP address in the SAN field of server's certificate, instead of the CN field. It's true that it will be a problem if your IP will change dynamically - that's why we need DNS domain name, and set up the PKI infrastructure. If that's a bit heavy amount of work for your team, see below :)
Is there some simple way to accommodate this situation? I'm far from
an expert on any of this, so it's entirely possible I've missed
something very basic.
Is there some simple way to set the name that the client uses to check
the server to be different than the name it uses to connect to the
server? That way I could just set a fixed name, use that all the time
and be fine.
You can directly use IP address to connect, and override the target name in the channel args. Note that the overridden name should match the certificate sent from the server. Depending on which credential type you use, it could be slightly different. I suggest you read this question.
Is there some way to get a gRPC client to not check the server
certificate? (I already have the server setup to ignore the client
cert).
Is there some other way to get gRPC to encrypt the connection?
Note that: Even if you don't use any certificate on the wire, if you are sure the correct credential type(either SSL or TLS) is used, then the data on the wire is encrypted. Certificate helps you to make sure the endpoint to which you are connecting is verified. Failing to use certificates will leave your application to Man-In-The-Middle attacks. Hope this can help you better understand the goals and make the right judgement for your team.
We have equipment which have public IP addresses and we don't have SSH access to it. In order to secure their login screens, we need to use the HTTPS, but when we do that it is always complaining about insecure connection due to wrong SSL certificate. I am aware that we cannot issue SSL cert on an IP, but the other problem is that we don't have access to the equipment either in order to install a new SSL certificate. So what are the security recommendations in this case. Is the traffic still secure and encrypted in case of SSL mismatch.
I know that we can limit the networks who have access to this IP, but are there any other security measures?
Your main problem here is an active attacker. When you connect via HTTPS, the server will send its certificate, claiming to be the web server where you're trying to connect (let's call it "SecureServer"), and the Certificate Authority (CA) will be the one in charge of letting you know if "SecureServer" really is who it claims to be. When using a self-signed certificate or something like that, there'll be a warning letting you know that it's not a secure connection, because there's no way to verify that "SecureServer" is really who it claims to be, after all, you're not a CA, and because of that, you can even create certificates for "google.com", but since you aren't an authority, nobody's going to trust you.
Now, the problem here is that if someone wants to connect to your device, they'll see that warning and they'll be like "oh yeah, that happens all the time. Just skip it and keep working", but an active attacker can intercept that communication, add his own certificate, instead of the server certificate and voilá, now he'll have access to your encrypted communication, because now the communication is between you and the attacker, and if you're waiting for a response from the server, he can also establish a communication with the server, so he'll forward all your requests to the server, while reading all your requests and server responses. All this is possible because once the active attacker has intercepted the communication, you'll see that warning, but all your users are used to just ignoring that warning, and they'll just accept the communication anyway, while when using a certificate issued by a CA, if they see that warning, they'll know that there's something wrong.
Honestly, for me, the best thing that you can do here is to use a certificate issued by a CA. Also, according to this answer, you can issue an SSL certificate on an IP address (I've never tried it before, but it might be worth to give it a try). You also mentioned that you don't have access to the hardware to install that certificate, but I'm guessing that you can request that to someone who has access to it, just explain the situation and if he/she is a reasonable person, he/she will understand the problem and will install a new certificate. Because honestly, just limiting the IPs range or something like that, is just a workaround for something that should be implemented correctly.
I've a quick question:
I have 2 websites, 1 has some links to file downloads. Those files are hosted on another server.
I need to encrypt the request data between the 2 servers..can I do it just using a SSL certificate?
Any other/better idea?
Those files are private docs, so I don't want the server 2 or any other people being able to track the file requests between the servers.
Thanks
Yes, use SSL (or actually TLS) if you want to achieve transport level security. If these are two servers that you control you can configure your own self signed certificates. If you want to make sure that only the two servers can communicate with each other, then require client-authentication, where both the server and client use a certificate/private key pair.
Most of the time the trick is to implement a sensible key management procedure. Setting up a web server to handle TLS using certificates should not be too hard.
SSL certificate will work fine for ensuring the transfer is encrypted. Even just a self signed certificate will be fine for this purpose (provided you can tell the client you're going to use to accept the self signed cert)
Alternatively if it's two linux machines then scp (secure copy) is a great tool where it'll connect via ssh and grab the files. (There probably is a windows scp tool but I don't know it)
Rsync also supports going via ssh
As for tracking the request... there's nothing you can do to prevent any device between your computer and the destination computer logging the fact a connection was made but the encryption should prevent anyone from getting to the actual data you're sending.
Issues have been asked many times about how to handle self-signed certificates with Java and implementations are often provided. However, I'm not sure that these implementations will give me the security/trust I am looking for.
My circumstance is as follows: I have a client program connecting to our server application. Both of these we have complete control over. Our client post's a stream using https to a URL at our server, and the server responds. Currently (and this is what I'm trying to fix) the server has a self signed certificate. Java doesn't like this and FOR TESTING ONLY, we are pretty much ignoring the certificate altogether by trusting any certificate.
I have little knowledge of SSL. My boss says we can use our self-signed certificate and it will be secure as long we don't make our crypt. key public. This sounds correct to me, but a lot of posts say self-signed cert's are automatically vulnerable to man-in-the-middle attacks. Does this mean SSL sends the crypt. key along with the certificate?
Since we have control over both ends, should we just encrypt our data ourselves with a secret key, and decrypt it at the end using our key? Or is there reason to use SSL?
Instead of trusting any certificate blindly (which would make the connection vulnerable to MITM attacks), configure your Java client to trust that particular certificate. Self-signed certificates do not inherently make SSL/TLS connections vulnerable to MITM attacks, they just make their distribution and the evaluation of trust more specific to this particular deployment (i.e. you have to configure it manually).
You can do this in at least 3 ways (pick the easiest one for you, I'd suggest bullet point #2):
Import the server certificate into your client's global trust store (lib/security/cacerts in your JRE directory). This will make all applications run with this JRE trust this certificate.
Import the server certificate into another truststore (possibly a local copy of lib/security/cacerts) and make this particular application use this truststore. This can be done using the javax.net.ssl.trustStore system properties.
Make your client application use an SSLContext initialised with an X509TrustManager configured to trust that certificate: either something written manually or a trust manager coming from TrustManagerFactory initialised by loading a local keystore that contains that particular certificate (as in the previous method).
You'll find more details about all this in the JSSE Reference Guide.
(This answer to a similar question should give you the details for doing all this properly, in particular keytool -import ....)
The arguments against self signed certificates mainly apply to web-applications. Since with the current infrastructure a browser won't be able to validate your self-signed certificate.
Since you have control over the client, you can simply hardcode the certificate you expect into the client. For example you might calculate the sha1 hash of the certificate, and check if that matches the expected value. That way you don't even need to trust hundreds of CAs.
To achieve secure communication you need to first ensure your talking to the right computer. When the client first attempts to establish a secure connection, it pings the server and the server responds with its cert. At this point you MUST validate the servers cert before continuing. The cert includes a public key and signature that can be used to ensure the cert is valid. For example, in web browsers this means checking to see it's been signed by an authority listed as trusted in your browser settings, if that check fails you'll see red warnings in your browser. In your case this will mean you have manually (or in code) added the servers cert into a trust store so that it is trusted.
I have a Client-Server-Application, which allows users to run any code on the server over network. I want to protect the user from connecting to some other server, that behaves like the real thing, but steals passwords, how can I do that?
Neither the Server nor the Client can be expected to have internet access, the certificate authority is out of the question. Is there any other way to verify that it's my code I'm talking to, even if someone gets the source code?
The simplest solution is using SSL with a self signed certificate. Then hardcode the server's certificate into client. Most SSL libraries offer some way to roll your own certificate validation logic, or change the collection of valid CAs.
This assumes you can keep the server's certificate secret.
In principle SRP could be an alternative. But you should not implement it yourself, since it's very easy to make subtle mistakes that appear to work, but make the system insecure. Some SSL libraries, such as GnuTLS have support SRP.
Is your attacker likely to gain root access to your real server? If not, then you can establish a self-signed certificate (as suggested by CodesInChaos) and rely on operating system permissions to prevent unauthorised users from reading the private key file. You can then be confident that your clients are only connecting to your real server (via SSL).
If an attacker can gain root access to your real server, you have many problems to deal with. Firstly, the attacker can read process memory at will, so any sensitive materials exposed in server memory (such as the passwords you mention) will be accessible. Also, the attacker can steal your private key and establish their own server (although why would they, when they can simply snoop on your real server memory).