Java 7 applet self signed certificates - java

I've been trying to adopt myself and my applet to the new security constraints imposed in Java 7.
My applet is self signed and as such, it was automatically blocked. After adding the site to the exception list in the java configuration console I managed accessing it but not without having to see that annoying message shouting at me that the signer is UNKNOWN, requiring me to approve running the applet.
This one is really annoying as it requires my approval each time I try to load the applet...not storing my previous approval...
so, I found this document which should have solved all my problems as the distribution of my applet is within a known community. I followed all the guidelines, created the certificate and entered it into the store that is used by the JRE (I also see that certificate from the configuration console) but the annoying approval message keeps popping and saying that the signer is still UNKNOWN...
any idea, what I'm missing? it looks like the addition of the certificate into my store had no impact on the flow whatsoever...
thanks in advance.
GBa.

Unfortunately mentioned certificate fields are not provided so maybe my guess is wrong but I would suggest that you create a certificate where the Common Name in the Subject field matches the signing authority address. There are three ways to have a match and eventually avoid the warning:
1. The host name (in the address bar) exactly matches the Common Name in the certificate's Subject.
2. The host name matches a wildcard common name. For example, www.example.com matches the common name *.example.com.
3. The host name is listed in the Subject Alternative Name field.
The most common form of SSL name matching is for the SSL client to compare the server name it connected to with the common name in the server's certificate.
If an SSL certificate has a Subject Alternative Name (SAN) field, then SSL clients are supposed to ignore the common name value and seek a match in the SAN list.

Well, I finally found the problem...
It turns out that once I cloned the trusted.certs (deployment.user.security.trusted.certs) file into trusted.cacerts (deployment.user.security.trusted.cacerts) file, everything started working...
I do not understand what the difference is between the two stores, futhermore, in the link that I added in the question (this), it talks about the certs file for individual usage and so... it made sense to me that it should work... however, it turns out that Java thinks differently :-)
anyways... this is the answer.
thanks everyone for your collaboration,
GBa.

Related

How to solve "The certificate is not valid and cannot be used to verify the identity of this website" error?

The question is, How to solve "The certificate is not valid and cannot be used to verify the identity of this website" error?.
Here are the details:
I have a signed applet that has been working fine, until I updated Java to 8u25 (1.8.0_25-b18). Now, the application shows an alert message "Do you want to continue? The connection to this website is untrusted". There is a note in this message too, "The certificate is not valid and cannot be used to verify the identity of this website".
The applet is loaded without problems. But when the user tries to use a specific function of that application, the warning message is displayed.
I've checked the java console when this happens, and this warning message is displayed right after these lines:
security: Obtain certificate collection in SSL Root CA certificate store
security: Invalid certificate from HTTPS server
network: Cache entry not found [url: https://sub.domain.net:9876, version: null]
The application is downloaded from a different domain, say "https://app.domain.net/.....", so no jars are downloaded from "https://sub.domain.net:9876", but the applet connects to "https://sub.domain.net:9876" to send/receive data.
The applet is signed correctly, and so far, it meets all the security requirements according to Java. This issue seems to happen when the application tries to connect internally with an HTTPS url like https://sub.domain.net:9876. That sites' SSL certificate is valid, issued by GoDaddy and has not expired.
Again, this started to happen after updating my JRE to 8u25. I've tested adding the offending URL to Java security exception list, with no success.
Here are a few screenshot of this problem:
This is the warning message displayed:
Edit 10/18/2014:
Question posted in "Oracle Community" too, to increase answer options:
Question in Oracle Community.
Edit 10/21/2014:
I noticed this: When I click the link "More Information" displayed in the "Security Warning" dialog, the reason displayed says:
The application is being downloaded from a site other than the one
specified by the security certificate.
Downloading from "sub.domain.net"
Expecting "*.DOMAIN.NET"
This message says the application is BEING DOWNLOADED FROM "sub.domain.com", and that is false. The application (applet) is already downloaded, and it is only using that domain in an internal HTTPS request, to get/send business data, not to download additional Jars, JNLPs, etc.
I found how to solve this issue, and thanks to Steffen Ullrich for a valid proposal.
This is related to the certificate's Common Name (CN) value. In my case, that value was *.DOMAIN.NET, and to change it to *.domain.net, all we had to do was a procedure called "Domain Transfer". This means, to change the CN to *.REKEY.DOMAIN.NET, and then to change it again to *.domain.net. We could not change it to *.domain.net directly because the certificate provider says *.DOMAIN.NET and *.domain.net are the same.
Now, this issue happened only with Java 7.71 and Java 8.25. Previous version of Java 7 and 8 don't have this issue (SSL certificate restrictions for CN in a different casing).
Anyway, this solved the issue, and now we receive a gentle information message about the domain:
If you trust the certificate and the website you are accessing, hit Continue to get past this message.
However, unless you ABSOLUTELY trust that website, this is a red-flag warning that you may not be accessing the page you think you are, and there may be a serious security risk. That's why it warns you. A "wildcard certificate", if that is indeed possible, would be a Bad Idea unless it restricts itself to a very specific and limited set of domains.
I doubt this is case-sensitive.

Java Security Warning SSL Connection after server change

After a server change, I get nasty SSL warning in browsers (tested FF & Chrome), when loading an applet, used in an JavaEE Application (Serlvet API 3)
The warning says: "Certificate is not valid, and cannot used to identify the website"
The more detailed warning says: "The certificate authority, who provided the certificate, is not trusted." The messages are translated into english, so please excuse slight differences there. After this message, I get the message of Java, which shows that the Applet is ordinary signed (the dialog with the blue sign). So the Applet is working, only the warning message annoys.
Before I moved to another server, everything was fine and worked. No security warnings or anything else. The Applet is signed, by a certificate, which I requested from an CA. (rapidssl)
The old server environment was just a common web space, offered by 3rd party hoster. Now I moved to my own server, which utilizes XEN for hosting VMs. On one of that internal vm's, our webserver is deployed. According to that, I defined firewall rules to route traffic http/https to the vms.
Also the domain was ported, was purchased at old hoster, and the ip of new server is bound to domain.
I use Tomcat 7 as Application Server on an debian based OS.
In old environment, I could use the specified url in CN of my wildcard cert.(e.g. *.domain.com)
In new environment the basic message says: *.domain.com:port is not a trusted site.
I thought actually, that SSL Certs are independent of the used port. I've read that, on some research too. I also searched here in many threads, but the supposed answers didnt work for me.
The certificate and root cert. are imported to Java's own keystore cacerts. In Tomcat 7, I use the JSSE Implementation for SSL, with properly setup keystore files.
I've tried already this, but as im not that experienced with SSL/TLS Technology, the tried solutions maybe even wont solve my problem:
Disabling SNI in Tomcat 7 (dont work)
Adding Host aliases in server.xml (dont work)
Can anyone clarify, what the actual problem is, or has experienced the same issue ?
#edit: The are no error stacktraces in any logs, which I could provide here, also no exceptions gets thrown.
It came clear, thanks to Khanna111 Gaurav Khanna and jwv, that the certificate chain wasnt setup properly. I thought, if there were any problems with the certificate chain, that the browser will notify me about it. It isn't like that.
As we migrated from old hoster to new server, they provided only the certificates, but without the private key.
As im not that much experinced with SSL, I thought that importing the intermediary certs and the acquired cert is enough.. It is not :)
After stumbling on
intermediate-ca-certificate-in-java (link in comment), I've read this, which solved my problem: why doesn't java send the client certificate during SSL handshake? & external website:Import private key and certificate into Java Key Store (JKS)
I had certkey.key,publiccert.crt, intermediate_primary.cer and secondary_primary.cer Files.
The first step was, to convert the .key and .crt file to DER format, as mentioned in last link
via OpenSSL due to keytool's inability to import a key in an existing keystore
After converting to DER Format, I used the Tool ImportKey and created a new keystore with key/cert contained.
The second step was following the instructions of second link (Bruno's Answer), so it was copy&paste the certificate contents, into a single file. After importing the bundle of certificates into keystore, everything was fine.
I hope this can help anyone else, which is also not that familiar with SSL.
p.s. due to my lack of rep, i cannot mention all sites, I've used.. I'll provide them in comments

Validate Extended Validation(EV) of SSL certificate using JSSE

I got list of URLs, and I want to validate their Extended Validation (EV) attribute using JAVA
I can make request and get their certificate, but I am not sure how to validate “Extended Validation” for a given site.
Is there any special value in certificate? Or any attribute?
Extended validation is mostly useful from a user-interface perspective. It's not so useful if your client doesn't have anything in its user interface to display the certificate. These verifications are not integrated by default in the JSSE, possibly because there is little demand for it (lack of Java browsers). (By the way, you should verify the certificate you get upon connection, not check with a first connection and connect with another, just in case).
The specifications are defined by the CA/browser forum.
The OID values and root CA certificate fingerprints are hard-coded into browsers (see security/certverifier/ExtendedValidation.cpp in Firefox, used to be in in security/manager/ssl/src/nsIdentityChecking.cpp). There is also a list on Wikipedia for reference, although in principle you should check the policy OIDs with each CA.
To analyse the extensions, it might be useful to use BouncyCastle if X509Certificate.getExtensionValue() isn't enough.
One problem you will have to watch out for is that the hard-coded SHA-1 fingerprints of the root CA certificates need to match exactly those certificates in the trust store. Some CAs renew their CA certificates once in a while in the bundles that are shipped with most browsers/OS/JREs: make sure you're using the same.

How are SSL certificate server names resolved/Can I add alternative names using keytool?

These may be phrased as separate questions for clarity, but they are all related to the same issue.
How are SSL certificate server names resolved?
Why do browsers seem to use the CN field of the certificate, but Java's mechanism seem to only look at "subject alternative names" only?
Is it possible to add alternative names to a SSL certificate using keytool?
If not, is using openSSL instead a good option??
Just a little background: I need to get a main server to communicate with several servers using HTTPS. Obviously, we don't want to buy SSL certificates for every server (there could be many), so I want to use self-signed certificates (I have been using keytool to generate them). After I add the certificates as trusted in the OS, the browsers (IE and Chrome) happily accept the connection as trusted. However, even after adding the certificates to Java's cacerts, Java still won't accept the connection as trusted and throws the following Exception:
Caused by: java.security.cert.CertificateException: No subject alternative names
present
at sun.security.util.HostnameChecker.matchIP(HostnameChecker.java:142)
at sun.security.util.HostnameChecker.match(HostnameChecker.java:75)
at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkIdentity(X509T
rustManagerImpl.java:264)
at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(
X509TrustManagerImpl.java:250)
at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(Clien
tHandshaker.java:1185)
... 14 more
I found that I can make Java trust the certificate implementing my own HostNameVerifier, which I copied from here: com.sun.jbi.internal.security.https.DefaultHostnameVerifier just to test (by the way, the hostname passed as an argument to the HostnameVerifier is correct, so I think it should have been accepted).
I have been using the certificate field CN as the hostname (usually the IP address).
Can anybody please tell me if I am doing something wrong and point me in the right direction?
How host name verification should be done is defined in RFC 6125, which is quite recent and generalises the practice to all protocols, and replaces RFC 2818, which was specific to HTTPS. (I'm not even sure Java 7 uses RFC 6125, which might be too recent for this.)
From RFC 2818 (Section 3.1):
If a subjectAltName extension of type dNSName is present, that MUST
be used as the identity. Otherwise, the (most specific) Common Name
field in the Subject field of the certificate MUST be used. Although
the use of the Common Name is existing practice, it is deprecated and
Certification Authorities are encouraged to use the dNSName instead.
[...]
In some cases, the URI is specified as an IP address rather than a
hostname. In this case, the iPAddress subjectAltName must be present
in the certificate and must exactly match the IP in the URI.
Essentially, the specific problem you have comes from the fact that you're using IP addresses in your CN and not a host name. Some browsers might work because not all tools follow this specification strictly, in particular because "most specific" in RFC 2818 isn't clearly defined (see discussions in RFC 6215).
If you're using keytool, as of Java 7, keytool has an option to include a Subject Alternative Name (see the table in the documentation for -ext): you could use -ext san=dns:www.example.com or -ext san=ip:10.0.0.1.
EDIT:
You can request a SAN in OpenSSL by changing openssl.cnf (it will pick the copy in the current directory if you don't want to edit the global configuration, as far as I remember, or you can choose an explicit location using the OPENSSL_CONF environment variable).
Set the following options (find the appropriate sections within brackets first):
[req]
req_extensions = v3_req
[ v3_req ]
subjectAltName=IP:10.0.0.1
# or subjectAltName=DNS:www.example.com
There's also a nice trick to use an environment variable for this (rather in than fixing it in a configuration file) here: http://www.crsr.net/Notes/SSL.html

Using certificates in a client-application consuming a web service

I am implementing a VB.NET desktop application which consumes a web service.
The web service implemented in Java and I currently using Tomcat on my localhost to host the web service.
The web service requires secure communication with the client and so I have followed instructions that outlined how to use Java's keytool.exe to create two .jks keystores (one for the client and one for the server) and then create two .cer certificates (one for the client and one for the server)
I have placed the keystores and certificates generate into the directory where the web service is expecting them (according to the instructions)
I have installed the certificates into TrustedPeople and have attempted to use the certificate by setting the ClientCredentials.ClientCertificates property like this:
myServiceProxy.ClientCredentials.ClientCertificate.SetCertificate(storeLocation.CurrentUser, StoreName.TrustedPeople, X509FindType.FindByIssuerName, "name")
I keep getting the following error message when I try to call any method:
An error was discovered processing the <wsse:Security> header
My problem is that I don't know how to use this in the VB.NET client application that is consuming the web service. I could be doing this completely wrong. Any guidance on this topic would be greatly appreciated.
Thank you,
-Frinny
While I haven't coded VB for 10 years, this should get you started: http://www.example-code.com/vbdotnet/ssl_client_certificate.asp
especially this looks like it is loading the file containing the certificate:
certStore.LoadPfxFile("chilkat_secret.pfx","secret")
and this extracts the certificate and uses it for the connection:
Dim cert As Chilkat.Cert
cert = certStore.FindCertBySubjectCN("Chilkat Software, Inc.")
If (cert Is Nothing ) Then
MsgBox(certStore.LastErrorText)
Exit Sub
End If
socket.SetSslClientCert(cert)
When I had to work with certificates and WS, I had lots of issues with the them too. Use the certificates MMC and verify:
That you placed the certificate in the correct place. Note that there is a CurrentUser store, Machine Store etc. Make sure you put the certificate in the correct one according to your code.
Which user is running your application? Is the certificate located in it's store? The certificate must be visible to the user.
Open the certificate and make sure it is trusted (you will see a warning if not). You may need to put your CA's certificate in Trusted Certification Authorities store.
Make sure that the algorithms you use on each side are supported by the other side.
Note that you are looking for the certificate by issuer name X509FindType.FindByIssuerName, "name" open the certificate, make sure the issuer name matches (I guess not since it seems like copy&paste from example).
If all of this fails, try to experiment with the certificate location (I vaguely remember some issue with being able to use certificates from one location and not the other), and with the property you use to search for the certificates.
Plus, since you asked about certificates I answered about certificates. It's a good idea to check if there's an inner exception and see - it may be another problem.

Categories

Resources