As luck would have it, I've been recently tasked to find a substitute for the Hardware Security Module that, for a handful of reasons, would no longer be able to serve us.
What is a HSM?
HSMs are server appliances, built on top of PKCS #11 in order to take advantage of the cryptographic functions, while maintaining a high level of security for the keys that it holds. The authentication, encryption, decryption, signing and all manner of connections to it are logged. They usually come with cryptographic security tokens that make sure you need to be physically present, to even perform any sensitive operation like reboots.
Sitting on the application server is an agent that would already have had a certificate exchange with the HSM appliance. The application need only to liaise with this agent, that will handle the communication with the HSM server.
The hunt
It would have been an easy job, had we only require asymmetric keys. Any old JKS, or PKCS #12 archive (for better compatibility outside of Java) stored within the application server would work. Except that our application require use of symmetric keys. The problem is, most keystores (a concept mostly within Java) only support private key and certificate pairs. They cannot handle storing secret keys.
Enter JCEKS. The Java Cryptographic Extension Key Store can carry private and secret keys alike. The next closest thing is from Bouncy Castle, with their BKS/UBER. A quick browse-through using KeyStore Explorer should suffice to show you their differences from JKS and PKCS #12. But I did take a little bit further to confirm that both Oracle and IBM variety of the JRE does indeed not support generating secret keys into PKCS #12 keystores, just because this claimed it possible. The runtime throws an exception because you'd have to pass in a null for the certificate, when PKCS #12 expects a certificate.
Any answers?
The valiant effort of OpenDNSSEC with providing a SoftHSM, proved too complicated beyond my comprehension. Whereas an Italian job - j4sign - requires an actual smart card as part of their recipe.
Somebody did suggest to encrypt the secret key with an asymmetric key kept in a keystore, and store it alongside in the filesystem. I see where he's coming from, but I'd feel naked and exposed not containing the key within the archive. It's plausible; just not ideal.
So what do?
I'm sticking with JCEKS for the time being. My counterparts working on C++ may need to put in some effort, while we sort this out. But to the best of my abilities, I've tried providing a wrapper JAR (that basically behaves like the HSM agent) for them to take advantage of the JCE keystore. It's still a work in progress, so if I can't convince them to make it work, we'll need to come up with an alternative, and fast.
The journey continues!
If you have any inkling of all these shenanigans, hit me up and let me know your thoughts.
Information Technology is a funny monster. Sometimes as docile as Toothless, other times scarier than SCP-173. And just when you thought you'd tamed it, Experiment 626 sets your house on fire. The web is where you can find everything there is to know about the quirks of IT.
Sunday, June 14, 2015
Friday, April 10, 2015
jaxb.properties
A client was looking through the JRE console output with trace enabled. He saw the network communication going on while JAXB was trying to locate an implementation for the SAXParserFactory that I have included in my applet. It looked a bit like this:
network: Connecting https://my.url.com/my-project/com/project/result/jaxb.properties with proxy=DIRECT
In essence, the JRE tries searching for the file in-depth from the server repeatedly, causing what he amounted to increased latency across the board when accessing our application. I looked up the javadoc for SAXParserFactory on the sequence of events. This place spelled out the default implementation that's internal the Java. I simply placed into the annoying jaxb.properties file the following line:
javax.xml.bind.context.factory=com.sun.xml.internal.bind.v2.ContextFactory
This jaxb.properties file was added into the several locations that I saw popping up in my Java console that has a relative path from my applet project. The runtime found what it's looking for, and no longer searches for the same file in multiple other locations.
I'm aware that this file is leftover from the earlier versions of JAXB, but if Java is still churning out extra traffic while trying to hunt down a non-existent file, there will bound to be people that would much rather not have this extra step involved.
Edit: Apparently there's an even better way! This solution cuts through all the deprecated nonsense, by basically telling the applet to not do any lookups at all!
The Java console log output for JRE 7 (not visible in JRE 8) indicated the search was still on, but for META-INF/services/javax.xml.parsers.SAXParserFactory this time. In order to avoid adding extraneous stuff entirely, just add this param into your HTML:
And it's even more convenient this way!
network: Connecting https://my.url.com/my-project/com/project/result/jaxb.properties with proxy=DIRECT
In essence, the JRE tries searching for the file in-depth from the server repeatedly, causing what he amounted to increased latency across the board when accessing our application. I looked up the javadoc for SAXParserFactory on the sequence of events. This place spelled out the default implementation that's internal the Java. I simply placed into the annoying jaxb.properties file the following line:
javax.xml.bind.context.factory=com.sun.xml.internal.bind.v2.ContextFactory
This jaxb.properties file was added into the several locations that I saw popping up in my Java console that has a relative path from my applet project. The runtime found what it's looking for, and no longer searches for the same file in multiple other locations.
I'm aware that this file is leftover from the earlier versions of JAXB, but if Java is still churning out extra traffic while trying to hunt down a non-existent file, there will bound to be people that would much rather not have this extra step involved.
Edit: Apparently there's an even better way! This solution cuts through all the deprecated nonsense, by basically telling the applet to not do any lookups at all!
The Java console log output for JRE 7 (not visible in JRE 8) indicated the search was still on, but for META-INF/services/javax.xml.parsers.SAXParserFactory this time. In order to avoid adding extraneous stuff entirely, just add this param into your HTML:
<applet>
<param name="codebase_lookup" value="false">
</applet>
And it's even more convenient this way!
Thursday, March 26, 2015
Changes to applet JAR manifests for Java 7 onwards
Reading through this official page made me realise that it was not being specific about what needs to be done. The changes are being categorised into each Update without summarising what is the latest set of TODOs in order for your applet to be able to run properly. Here's my TL;DR of this page:
- MANIFEST.MF (required)
- Required:
- Application-Name: My Applet Name
- Permissions: sand-box/all-permission
- Optional:
- Codebase: {list of URLs}
- Trusted-Only: true (more secure)
- Trusted-Library: true (less secure than Trusted-Only)
- Application-Library-Allowable-Codebase: {list of URLs}
- Caller-Allowable-Codebase: {list of URLs}
- {list of URLs}:
- Can be a single asterix as a wildcard '*' for liberal use of the JAR
- Can contain a mix of named/IP addresses
- Single line, no linebreaks
- Example: http://localhost:9090 https://localhost:9443 some-other.internal.url 172.16.0.1
- Signing (required)
- Can be self-signed
- Should not be expired
- Within a secure intranet environment, it is possible to establish the following:
- A self-signed certificate identified as a Root Certificate Authority (Root CA);
- This certificate is added to all workstations within the network;
- Generate a separate certificate for this application JAR file;
- Sign the application certificate using the Root CA (e.g. 1 year expiry);
- Of course, you must be acquainted with the risks of being vulnerable to the CA certificate ever being compromised.
- Workarounds:
- Exception Site List
- Add your URLs manually into individual workstation JRE Control Panel
- Deployment Rule Set
- Create an XML according to this page;
- Better granular control over specific JRE versions you want your application to run using;
- Wrap the XML inside a signed JAR (e.g. using above Root CA);
- Push JAR into all workstations on startup.
Subscribe to:
Posts (Atom)