Need advice on Self-Signed SSL and Java - encryption

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.

Related

Why do we need HTTP instead of SSH?

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.

API Proxy SSL Assistance

I received the following question. Any help would be greatly appreciated!
What I need to be able to do is configure SSL to validate the target endpoint’s SSL certificate against the base trusted roots (typically provided by the OS and/or Java). There is no documentation that tells me how to turn on SSL certificate validation or if I add a TrustStore if it will guarantee that the SSL cert is validated against that. The only tutorial I see that is related is for SSL Client Auth, which we are not using.
Validation of backend SSL server certificates is explained on this page. Note that the page documents how to achieve mutual authentication, where the gateway would both validate the target server's SSL certificate (which you want), and send a certificate to the target as identification (which you do not want).
To validate the target's certificate, you create a truststore and upload all certificates in the trust chain for your target server. The documentation mentions only uploading the target server's certificate (which works if your target server is using a self-signed cert), but you'll want to upload the entire trust chain of certificates if you are using a non-self-signed cert. Creating and uploading to the truststore is shown in step 6 on the page above.
Then, you'll want the target endpoint configuration to look like this:
<TargetEndpoint name="default>
<HTTPTargetConnection>
<SSLInfo>
<Enabled>true</Enabled>
<ClientAuthEnabled>false</ClientAuthEnabled>
<TrustStore>myTruststore</TrustStore>
<IgnoreValidationErrors>false</IgnoreValidationErrors>
</SSLInfo>
<URL>https://myservice.com</URL>
</HTTPTargetConnection>
</TargetEndpoint>
ClientAuthEnabled=false indicates that the gateway will not send a certificate to the target.
IgnoreValidationErrors=false will cause the connection to abort if the certificate returned by the target cannot be validated using the certificates in the truststore. IgnoreValidationErrors=false is the default, so you could leave it out and it would work as desired. However, if you are having problems communicating with your target server, it may be useful during testing to set the ignore flag to true to allow communication even if the certificate fails verification (just to isolate your problem). Just be sure to set it to false in production.
The xsd schema for the SSLInfo element can be found here.

Choose Certificate with Smart Card Authentication IIS7 Server 2008

I am trying to set up smart card authentication for a website that I have created. Setting authentication to Windows and setting SSL to required I can get the smart card reader to pop up when they go to the web site. There are 2 credentials on the card though and only one of them is showing up as an option (the information I need is on the other credential). I asked a co worker and he said in IIS 6 there was a way to specify a location on the smart card to look for certificates. I have been researching this issue for about a week now but haven't been able to find a solution to this issue yet. Does anyone know how to do this?
IIS really only knows about certificate-based authentication, not smart-cards per se (which is really just a form of cert-based authentication). Configure your site to use certificate-based authentication, eg "Require Client Certificates" and IIS will chain the call down to Windows security, which, in turn, recognizes that among the sources for identity certificates is the smartcard reader. Depending upon your site requirements, you may also need to enable Certificate Mapping, which translates certificates into Windows account identities.
When certificates are required (or accepted) IIS will ask for a client cert in the SSL negotiation when the session is started. IIS will send a list of the Certificate Authorities it trusts to the client. The client then takes those and sees which match the list of Certificate Authorities it trusts. It then take sthe list of common entries and checks to see if it has any certs issued by a CA both sides trust. Generally, if there are none it will simply not send a cert and the request fails if the cert is required. If there is just one certificate IE will generally send that without asking the client which cert to send, but it will prompt for a PIN if required. Finally, if there are more than one certificate issued by a CA both sides trust then a dialog box will be presented to the client asking which cert to use.
In this case it sounds like perhaps the credential (certificate) you want the client to send is issued by a Certificate Authority that isn't trusted by one or both sides.

data encryption between 2 servers on file request

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.

How to protect passwords from a spoof server

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).

Resources