• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Tim Cooke
  • paul wheaton
  • Ron McLeod
  • Jeanne Boyarsky
Sheriffs:
  • Paul Clapham
Saloon Keepers:
  • Tim Holloway
  • Roland Mueller
Bartenders:

validating SSL certificate using java Apache http client

 
Ranch Hand
Posts: 594
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

I'm using java and Apache Http client to access a Public Rest API. I got the Rest API's URI by just google search. When I looks at the URL, it says https, and the SSL certificate is issued by "Amazon".

So my question is how to verify the certificate at java code, if possible could you please provide any sample code to validate the certificate?
 
Rancher
Posts: 326
14
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Let Java do it for you (yes, it's done explicitly the very long way):

run it with: java -Djava.security.debug=all TLSTest - and you may get this output (trucated as the log is about 100kb):
 
jacob deiter
Ranch Hand
Posts: 594
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thank you Benford for your reply!

I am using Apache Http client tool to access the Rest API.  How it can be done in Http client?

P.S: I am not sure how genuine the Rest API is, if the API is not secure enough then I do not want to call it from Http client tool.
 
Sheriff
Posts: 22862
132
Eclipse IDE Spring TypeScript Quarkus Java Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
If the root certificate is issued by Amazon, you probably don't have to do anything. Java comes with a set of pre-defined trusted root certificates.

If you need to use custom certificates, you need to create a connection manager using something like this:

The SSLContext can be built using SSLContextBuilder, it has methods to create an SSLContext that uses specific trust key stores.


@Matthew: you don't need to explicitly load the cacerts truststore, that's done by default.
 
Saloon Keeper
Posts: 28804
212
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

jacob deiter wrote:P.S: I am not sure how genuine the Rest API is, if the API is not secure enough then I do not want to call it from Http client tool.



That depends on what part of the system you're talking about. You can have sloppy code on client and/or server, but HTTPS provides a secure channel between the two.

If you make a plain-text HTTP request to a server port that's configured for HTTPS, you will get an error because HTTP does not include encryption negotiation (or encryption, period). Conversely, HTTPS sent to an HTTP port will be seen as garbage by the server.

Normally, it's enough to request a URL with the protocol value "https" to ensure that TLS/SSL will be automatically selected by the client. And of course, if you don't explicitly specify, the request will target the server's port 443.

So you can be assured that SOME encryption will be used. The more serious concern is that the encryption algorithm used isn't one that has been "broken". That's primarily up to the JVM plus whatever plug-in algorithms you might manually introduce, and it's why having a recent JVM is preferable (keeping an eye on security bulletins). If you run into issues where you need to manually control which algorithms in the available set are / are not to be used, well I'll hand you back to Rob.
 
Matthew Bendford
Rancher
Posts: 326
14
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

jacob deiter wrote:How it can be done in Http client?


Pretty much the same way you do most crypto things in Java: Just use what ever client-code you have with some TLS secured endpoint. As you said you use some URL starting with "https://" it doesn't matter what you use as your client code:
(new URL("https://")).openConnection() works as well as going full blown like I did using raw sockets or some other lib like Apache Commons.
Unless some lib would re-implement TLS on its own - and I'm only aware of very few that actually do - it just has to rely on the crypto stuff SE-api comes with in its base package.
So, no matter what you use - it all ends up in a call to SSLSocket.startHandshake() either explicitly or implicitly - and if it's the first connection any call to getDefault() will result in some defaults set up in pretty much the way I posted - as that's the few lines buried very deep in the classes responsible for all the crypto stuff that Java can do all on its own without any additional lib.

Rob Spoor wrote:If the root certificate is issued by Amazon, you probably don't have to do anything. Java comes with a set of pre-defined trusted root certificates.


Be aware: On many Linux distributions Java uses a symlink to point at the CA-store often provided by packages like mozilla-ca. So it actually relies on the system wide installed CA certs rather than comming with its own set.
Windows binaries are often supplied with a good common set of certificates - round about 90 or so.

Rob Spoor wrote:@Matthew: you don't need to explicitly load the cacerts truststore, that's done by default.


I'm aware of that - in fact the lines I posted are what happen anyway the first time any getDefault() method is called: It ends up in SSLContext.init(null, null, null) which then in turn sets up some SecureRandom and loads the default cacerts file.
I did it on purpose cause OP seems a bit too much focused on using apache commons - although even that lib still relies on whatever the VM its run on comes with - as apache doesn't re-implement a full TLS stack on its own - at least not that I'm aware of it.

Tim Holloway wrote:The more serious concern is that the encryption algorithm used isn't one that has been "broken". That's primarily up to the JVM plus whatever plug-in algorithms you might manually introduce, and it's why having a recent JVM is preferable (keeping an eye on security bulletins). If you run into issues where you need to manually control which algorithms in the available set are / are not to be used, well I'll hand you back to Rob.


I'm not aware of any recent important security patches to the JSSE and JCE stuff - but in fact even with the newest Java16 you still can set up and use SSLv2 without getting any warnings. It's up to some own logic to check what SSL/TLS versions and ciphersuites are enabled for handshake - and what the connection ends up with.
 
Tim Holloway
Saloon Keeper
Posts: 28804
212
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Java SE 14 for Linux keeps certs in a binary file in JAVA_HOME/lib/security - which also has a cert blacklist file which is in text form. The cacerts file may be a keystore, but keystores don't appear to have a "magic number" that identifies them as such and I wasn't willing to do further research. The builtin cacert file probably does have an anti-tampering signature, since that's good practice.

However, that cannot be considered as the definitive cert set since you can import your own certs, Again, I'm too lazy to research the cert-finder mechanism for Java. I'm sure if they wanted to, they could tap other OS and web client sysfems as well, if desired.

More to the point, as Rob has said, even the third-party libraries tend to be built on the JVM's internal HTTP protocol services, which are vetted by security professionals. You COULD build your own transport and SSL up from raw sockets, but what would be the benefit?
 
Tim Holloway
Saloon Keeper
Posts: 28804
212
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Update: Yes, the cacerts file in my JVM is a keystore. It has 93-factory-supplied entries, including 4 top-level Amazon certs, plus certs for verisign, thawte, godaddy and letsencrypt. Neither Oracle nor Sun apparently went into the cert business, however.
 
Consider Paul's rocket mass heater.
reply
    Bookmark Topic Watch Topic
  • New Topic