I have some websites that redirect the user login to https, some user get scared when they see the warning as it says the site is not trustable or someone is trying to intercept their communication, so most of the users do not continue with the login procedure.
The fact is that i would like to avoid paying the big amount to get a valid certificate from one of those companies, as i am not making money with these sites, but i would like to keep the users credentials secure. is there a way to avoid this?
It would be enough if i can intercept the https redirection and display a message to the users explaining the situation.
Some widely accepted certification authorities offer a free certification path for Class 1 certificates (which make no assertion over the identity of the certificate owner, only that they control the subject; in reality, few people actually check SSL certificates for identity verification, so this is rarely a realistic concern—and given the non-commercial nature of your application, may not be a concern at all in this case).
One such certification authority (that I have used myself in the past) is StartCom.
No, you can't hide the message without using a cert that is endorsed by a recognized CA. That's a fundamental fact of internet security.
What you CAN do is, before that message comes up, explain that they will see the warning. You can tell them that in fact your self-signed certificate is not vulnerable if a CA gets hacked (which has happened), while the rest of e-commerce is compromised.
But they won't read the long explanation. The best you can do is prepare them and tell them that ONE TIME they have to trust that you are who you say you are.
Related
Is it possible for a java web application to get digital certificates installed in Browser. What I am looking for is I will read the digital certificate from the browser and based on the certificate, I will give certain access. I tried to search in stackoverflow but did not see any similar questions.
To make things more clear, we have users have company issued laptops and has company specific digital certificates installed. Now my web application should allow or deny access based on whether these digital certificates are available. From the browser I can see the certificates as shown in the following image
I am looking for some method like getting all the certificates based from httpservletrequest(i know its not available, but just giving reference so that someone can point out if api of some sort is available and if it is really feasible/). Read the certificates one by one and get details like who issued it, what is the expiration date, CRL Distribution points, etc.
I know it may be a dumb question and may have security flaw, but still going for it.
I've implemented HTTPS connection with servlet running REST api.
Device is able to connect to server using HTTPS.
Device is accepting server's certificate and establishing HTTPS.
How to make sure that the device accepts only a particular certificate? The intention is that someone should not be able to setup a fake server identifying itself as right server using self-signed certificate.
In a browser environment, user would see Chrome's crossed out https in the url and know that the certificate is not verified. How to ensure that for an app.
The procedure is called certificate validation and is pretty standard. Some classes and components perform validation for you, others leave it for your manual implementation and control.
Validation ensures (in ideal world) that you are connecting to the legitimate server, i.e. the server whose host name and the name in the presented certificate match. This requires that the server has acquired a valid CA-signed (we omit self-signed variants for lack of security and flexibility) certificate for the needed host name. So far so good.
Now you can either rely on pre-implemented certificate validation or implement your own or add your own checks to the pre-implemented validation procedure. Implementing your own validation is too cumbersome for your task, so let's assume that the client code you use already performs some validation (you have not specified what exactly code you use for connection so I can't comment on it). You can rely on it, however in some countries state agencies perlustrate traffic, and for doing this they acquire (or generate on-the-fly in some cases) certificates which are fake by nature but valid if we follow the validation procedure blindly.
So if you control both the server and the client and also you can implement additional validation (your client component or class lets you do this) then your additional check can be to compare the issuer of the certificate (or the whole certificate chain) to the issuer you know to be valid. This is less flexible and to some extent against the PKI rules, but this approach significantly reduces the chance for the fake certificate to be generated and accepted as valid. The idea is that you know what certificate you use and what CA you used (and maybe use in future), so you can store this information in the client and compare it during validation.
You can read more about certificate validation by simply searching here on SO for "certificate validation" - this is quite popular topic.
With Adobe Reader you can sign a document locally. Is it theorically more secure than if the document was transported to the server and signed on the server (not especially using adobe technology) ? Could the user contest that the document could have been tampered later on if done on server ? How to prove him wrong technically that it is impossible even when signed on server - for legal issue to be taken into account.
Are you living in the EU? I can describe the situation here. The legal aspects of signatures are sort of regulated by Directive 1999/93/EC. There will be an updated version of this, so there will be some changes in the details, but generally the Directive does distinguish between server-based signatures and signatures made by an individual locally, having sole control over the process.
Being in sole control of a local process has a lot of security advantages, among them:
Using what the Directive calls a Secure Signature Creation Device (SSCD), such as a smart card. Using a tamper-proof device is definitely considered an advantage, although it can still be exploited when the attacker is e.g. in control of the computer/OS the SSCD is attached to.
The "What you see is what you sign" principle that was vaguely described in the Directive. Ideally, you should be able to view the data you are about to sign on a trustworthy device. This is impossible to guarantee with server-side signatures.
Key escrow. If the server signs, the key is most likely also stored on the server. And it's very, very hard to implement a solution where a key is on the server where only clients may access it, it's much more often the case that you need to trust the party operating the server.
That said, it is possible to secure the transport from client to server using e.g. TLS and still having a reasonably secure service. But pertaining the law (at least in the EU), the notion of a "non-repudiation" signature, a signature which is meant to be issued by an individual person, is only possible in the context of "local signatures". Accredited CAs here won't issue non-repudiation certificates to legal entities for example, such a certificate will only be issued to a real person, typically on an SSCD.
The downside of SSCDs has been that it is very hard to roll out large-scale deployments of software that would make use of them, especially across company/state boundaries because there are still a lot of interoperability issues with the myriads of hardware, the cost and the plain and simple fact that it's just less convenient.
Anything could happen to the document on its way to the server. The connection could be MitM attacked, the server could have tampered with, etc. etc.
The #1 rule in crypto signatures is, that it must happen on a trusted machine in a trusted environment, preferrably before it even reaches a connected machine (i.e. offline, then transferred on a offline medium).
So in short: It should be signed on the client and nowhere else.
If the signature is made by the user (human operator), then it's a question of trust to the server where the key resides.
Normally "signature is made by the user on behalf on the user" means that the user owns the key which is used for signing. In this case it makes little sense to put the private key on the server. And if you need this scheme, then either the signature is made not by the owner or the signature is made not on behalf of the individual making it.
But technically signing the data on the server (as you describe) is possible and in properly implemented architecture the user should be able to get the signed copy back and manually validate the signed document to ensure that this is what he (or the server on his behalf) intended to sign.
Another question is whether the server doesn't (intentionally or due to security breach) use the private key of the user to sign anything besides the requested documents. This is extremely hard to ensure unless you have a server specifically crafted for exactly one operation (signing of something) and in this case you would probably deal with specialized hardware device (such as one offered by SafeNet), not with a generic Windows/Linux/... server operating system.
We have a distributed cryptography module in our SecureBlackbox product, which implements similar scheme to what you describe, but roles are usually reversed: the user possesses the key and uses it to locally sign the document which resides on the server and is not transferred to the client. In that module we use TLS to ensure security of the channel and signing is performed on the computer of the user, so the private key remains strictly secret. However, the scheme you describe is also possible to implement using that module.
I'm building an application that needs to open self-signed HTTPS SSL URLs in java. I've learned that you can bypass the SSL problems by adding a call to HttpsURLConnection.setDefaultHostnameVerifier() where you say what hostnames are allowed.
However, I have a second problem where my servers are running self-signed certs. So even with the hostname bypass I'm getting exceptions like:
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
I've looked around and the only solutions I've found is to add the certificate to the java key store, but this is a problem for me because I have no control over when or how they update java, and I've read that the keystore isn't preserved between updates, and I have no access to the system outside of the JVM.
My application will only make calls to a single server so if there was a way to bypass the self-signed restrictions, and never consult keystores, it wouldn't be a security problem, but is there a way to do this?
I'm building an application that needs to open self-signed HTTPS SSL
URLs in java. I've learned that you can bypass the SSL problems by
adding a call to HttpsURLConnection.setDefaultHostnameVerifier() where
you say what hostnames are allowed.
There are some misconceptions from your question:
Hostname verification is unrelated to whether the certificate is self-signed or not.
It is a verification that matches the domain you are trying to access with the certificate info (CN or Subject Alt Name).
You would need to configure the verifier if you needed to accept a certificate that did not match the url (not recommended at all!!!)
Concerning the self-signed.
This is irrelevant.
You can configure your application to load your custom truststore which would include the certificate your application will trust. In fact this is the best approach (than using Java's cacerts).
All you have to do is import the certificate in a keystore (JKS or PKCS12) and load it in your custom TrustManagers in your application.
Just google arround, plenty of examples E.g. self-signed-ssl
As much as I hate to say this, sometimes it's better to just go with the flow.
Java is attempting to make applications more secure through the use of proper SSL verification practices. In this case, it is succeeding: had you been able to tell the program "it's okay, accept the untrusted self-signed certificate", your program would have been vulnerable to a man-in-the-middle attack where Mallory puts his server (with its own self-signed certificate, just as valid as yours!) in between the host and the target it's attempting to communicate with. Then he proceeds to read all the traffic you thought was nice and safe, and you don't even notice.
So, your assertion that telling Java to "trust any self-signed certificate when connecting to this host" is secure is, regrettably, not correct.
You can get free, totally valid SSL certificates from StartSSL. They're good folks.
That's how PKI is supposed to work - you must have complete chain of trust from some trusted certificate stored in you keystore to your certificate. So you can
set you certificate as trusted
ask somebody already trusted (i.e. with trusted certificate in the keystore) to sign you certificate
Trying to bypass that is not good bad idea. You can install you certificate in some Java post-install hook, you may have some cron job checking it periodically or do it in exception handling. You can even download this way a certificate from the server and install it everytime it changes (extracting the cert with openssl is easy). But for god's sake, if you decide to do such thing, at least write some audit log about it to some third machine a make sure somebody reads it.
You can also write "hacker-friendly" on you doors. :)
(Note that when you're talking about "keystore" in your question, you're in fact talking about the trust store (which is a keystore). More details on this unfortunately confusing Java terminology are in this answer.)
My application will only make calls to a single server so if there was
a way to bypass the self-signed restrictions, and never consult
keystores, it wouldn't be a security problem, but is there a way to do
this?
Actually, it would be a security problem. Your application may indeed be intended to call only a single server, but the trust store is precisely there to help make sure you're connecting to the machine you intended to connect to. Without it, you wouldn't be able to know whether you're connecting to that server or a MITM server.
If you want the security provided by SSL/TLS, don't bypass these rules. (In particular, don't use a trust manager that will accept any certificate.)
I've looked around and the only solutions I've found is to add the
certificate to the java key store, but this is a problem for me
because I have no control over when or how they update java, and I've
read that the keystore isn't preserved between updates, and I have no
access to the system outside of the JVM.
Quoting myself from this answer (to a more specific question):
The right way is to import this self-signed certificate into the client's trust store, using keytool for example:
keytool -import -file server-cert.pem -alias myserver -keystore mytruststore.jks
You can either do it directly in the JRE's trust store (lib/security/cacerts), which may lack some flexibility, or do it in your own copy of this file, which you then set as the trust store (the default password is changeit or changeme on OSX). You configure this truststore globally for your application using the usual javax.net.ssl.trustStore* system properties (e.g. -Djavax.net.ssl.trustStore=mytruststore system property (and -Djavax.net.ssl.trustStorePassword`). [...]
You don't actually have to use the trust store provided by the JRE (and which may be updated regularly). You could import your self-signed cert into a new empty keystore, which you'll use as a trust store within your application (don't import the private key with it). How to discuss trust store management was in fact discussed in this question: nothing prevents you from using a different trust store specifically for your application or part of it (and in fact Sun/Oracle make no guarantee as to the suitability of the default trust store).
I'm building an application that needs to open self-signed HTTPS SSL
URLs in java. I've learned that you can bypass the SSL problems by
adding a call to HttpsURLConnection.setDefaultHostnameVerifier() where
you say what hostnames are allowed.
While it may indeed by slightly less of a problem if you only have a single self-certificate in your trust store, host name verification is also an essential component of the security provided by SSL/TLS. Don't bypass it, verify that the certificate you're connecting to matches the name you're trying to connect to. (To make an analogy, if you want to check someone's identity, you not only want to check the their passport was emitted by a country whose passports you trust, but you'll also want to check they have the right name inside, otherwise you could be in front of anyone from that country.)
Making the CN= RDN of the Subject Distinguished Name of your self-signed certificate be the host name of the server should be enough, although it's the legacy way of doing it. You may also want to add the Subject Alternative Name extension. More on this in this answer.
Generally speaking do not bypass the SSL "problems". These mechanisms are precisely in place to make the usage of SSL/TLS secure.
This question may seem like a novice, and perhaps 'stupid' question but please bear with me...
I'm still struggling to find a way to get my Java application to use a keystore located inside the JAR file, and I'm very tempted just to disable certificate validation all together using the method here. However, before I do so, I just wanted to confirm why you should not do this and whether those reasons actually apply to me.
I've heard that no certificate validation can make your application liable to "Man In The Middle" attacks (I think), but even if I am correct, I am unsure as to what these actually are so please could somebody explain. Though, if they are what I think they could be, I'm not sure whether my application ever be subject to them because, my application only uses an SSL connection to obtain data from my website, so users do not tell the application which URLs to visit - if that makes sense...
Here's, an attack scenario. Other's might want to contribute some more.
Your application accesses a URL. At some point along the way (any intermediate network hop), an attacker could position himself as a "man-in-the-middle", that is, he would pretend to be a "proxy" for your communication, being able to read everything that goes through, and even modifying it on the way: the attacker could act on behalf of the user, mislead him as to what information he gets, and basically access al data being transferred.
Enter SSL: your client receives a certificate from the server, with a valid key (Signed by a known certification authority, or present in your keystore). The server will then sign and encrypt all it sends using that key. If an attacker where to place himself in the middle, he would not be able to read the data (it's encrypted) or modify it (it's signed, and modification would break the signature). He could still block communications altogether, but that's another story.
So that's that... if you ignore your keystore, you can't verify any server side certificate, and you open the door to man-in-the-middle attacks.
Though, if they are what I think they could be, I'm not sure whether
my application ever be subject to them because, my application only
uses an SSL connection to obtain data from my website, so users do not
tell the application which URLs to visit - if that makes sense...
If you connect to a server via SSL and you don't do any authentication, effectively you are have no security.
You have no idea who is the endpoint you are talking to.
The fact that the user does not type in a URL, but the URL is a hardcoded URL to your site is irrelevant. A simple proxy that forwards the data from your client to the server can steal all your client's data since there is no kind of authentication (this is the Man in the Middle Attack).
I would suggest you put the code you are using to load the keystore so that you get help on that.
Otherwise, if you don't have any requirements on security and you don't have any sensitive data you should go for plain connection (i.e. non-SSL) so that your performance does not deteriorate due to the unecessary (in your case) SSL overhead