How does JCA/JCE and PKCS#11 work (together)? - java

I want to use a HSM (hardware security module) to create a signature of a XML file. I did a bit of research and am now a bit confused, though.
Can you please clarify those questions:
What is meant with a key handle in JCE? I have read about it, that it is just a handle and the key is stored somewhere else. How can that be? From my understanding I either load the key into memory and use it, or the signing is done completely by a HSM and I only get the result, right?
Does the PKCS#11 standard define a way so that the signature is generated in the HSM? I've read about tokens, but I am not sure about signing.
The featurelist of my HSM states JCE and PKCS#11 separately. What does that mean?
I thought PKCS#11 is a standard, and JCE defines classes to use that standard. Does JCE specify its own protocols?

What is meant with a key handle in JCE?
A key handle (in JCE, PKCS#11, or most other cryptographic APIs) is simply a reference that enables you to use a key without seeing its actual value. That is good: you can have the key permanently stored in a secure place (e.g. an HSM) with the assurance that nobody will be able to copy it and run away with it - as it may happen if the key is the application space. Unlike a physical safe though, you can still perform cryptographic operation without running any security risk of key leakage.
Does the PKCS#11 standard define a way so that the signature is generated in the HSM?
PKCS#11 is a C API for cryptographic tokens. A token is a PKCS#11 abstraction for any device or program that offers services described by such API. The API defines which operations you can perform using the objects inside the PKCS#11 token: some objects are non sensitive, and can be extracted (e.g. public keys); some others are sensitive and can only be used, via handles.
If you have a handle to an object that supports signing, you can use the C function C_Sign to ask the token to authenticate some data provided by your application. The key does not leave the HSM.
The featurelist of my HSM states JCE and PKCS#11 separately. What does that mean?
Your HSM supports JCE in the sense that it comes with a native library that qualifies as a Cryptographic Service Provider.
It supports PKCS#11 in the sense that it comes with a native library that offers a C PKCS#11 API.
I thought PKCS#11 is a standard, and JCE defines classes to use that standard. Does JCE specify its own protocols?
Indeed PKCS#11 is a standard; but it is not directly usable by languages other than C. You need a mapping layer that translates it into something compatible to your language. A PKCS#11 library (and the physical tokens that it abstracts) can be mapped to a JCE provider.
However, a JCE provider may have nothing to do with PKCS#11.

Related

why does JcaPEMKeyConverter have a setProvider method?

I get why java.security.Security has an addProvider method - because Java has multiple providers that can provide stuff like javax.crypto.Cipher.getInstance() can use (sun.security.provider.Sun, org.bouncycastle.jce.provider.BouncyCastleProvider, etc).
But why does org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter have an addProvider method? Given the namespacing being used I find it hard to imagine that any "provider" other than BouncyCastle would provide a drop in replacement...
It's correct that the API is not designed on the assumption that the user has to use BouncyCastle for the provision of cryptographic services - and a ready example of this is people using a FIPS provider, such as BCFIPS.
One small correction though to the preceding answer, there is no license fee or similar for the BCFIPS Java provider and as one of the members of the project I'm more than a little disturbed to see someone stating that. I would be curious to know where that was heard from.
We do have a support program for FIPS and non-FIPS users and it does provide early access to the in-progress FIPS releases as part of it and that does cost (that's how we fund everything). However, the actual released FIPS jars, once published on bouncycastle.org are licensed under the BC license, which is basically the MIT X11 license, like all our other published work. I hope this clears up the confusion.
I don't know what 'namespacing' you think is being used. JcaPEMKeyConverter uses JCA to implement the crypto operations it needs, and it can use any JCA provider that provides the needed operations; nearly the whole point of JCA is that providers use the same API (or technically SPI, Service Provider Interface) so that you can selectively use different providers for the same operation(s).
Some, perhaps most, of the operations in bcpkix bcpg and bcmail libraries can use either JCA API (using any suitable JCA provider(s)) or Bouncycastle's own private API (using only Bouncy code), e.g. org.bouncycastle.pkcs.PKCS12MacCalculator[Builder] are interfaces with interchangeable implementations org.bouncycastle.pkcs.bc.BcPKCS12MacCalculator[Builder] and org.bouncycastle.pkcs.jcajace.JcePKCS12MacCalcuator[Builder]. (Bouncy isn't as careful as one might wish about distinguishing JCA from JCE in names consistently.) However, JcaPEMKeyConverter comes only in the JCA form.
It is true someone who has Bouncy add-on libraries will often have and be able to use the Bouncy provider as well, but not always. For example, US federal government systems are required to use certain cryptographic functions (mostly primitives) that are validated under FIPS140 (currently at revision -2, soon -3), and while Bouncy does have a FIPS140 implementation, using it commercially requires payment, while if you are using e.g. IBM Java on certain IBM systems it has providers (different from the common Sun/Oracle/OpenJDK ones) that are FIPS140 validated at no additional charge.

Bouncy Castle as provider v/s Bouncy Castle API

I have a case where I need to encrypt some files using OpenPGP. I am using Bouncy Castle to do so.
As I understand it Bouncy Castle encryption can be used in java in two ways:
I add Bouncy Castle as a provider and continue to use the standard Java libraries.
I use the classes specified in the Bouncy Castle library directly.
I wanted to know the pros and cons of both the ways and which method is recommended.
Also if I am using the second approach then why do I still have to add Bouncy Castle as a security provider. If I do not do so then I get a "No Such Provider" exception when I execute the following line:
PGPEncryptedDataGenerator encGen =
new PGPEncryptedDataGenerator(
new JcePGPDataEncryptorBuilder(PGPEncryptedData.CAST5).setWithIntegrityPacket(withIntegrityCheck).setSecureRandom(
new SecureRandom())
.setProvider("BC"));
As I understand it Bouncy Castle encryption can be used in java in two ways:
I add Bouncy Castle as a provider and continue to use the standard Java libraries.
I use the classes specified in the Bouncy Castle library directly.
I wanted to know the pros and cons of both the ways and which method is recommended.
The Java JCA is a better designed and certainly better documented API. It has better defined exception handling, more up to date parameter handling (ByteBuffer).
Furthermore, through the use of the provider abstraction, it can be enhanced not just with software based providers such as Bouncy Castle, but also with platform functionality and hardware providers. So if you program against the JCA you'll be rewarded with a more flexible runtime.
On the other hand the lightweight crypto API is a relatively low level API that provides a lot more functionality in a relatively well structured fashion. If you use it you're basically choosing Bouncy Castle as your sole provider of functionality. Bouncy Castle contains specific implementations in Java code only, which means that you won't get (much) hardware support.
Bouncy Castle's lightweight API doesn't have jurisdictional restrictions (such as 128 bit AES keys). So you can use it for your own protocol if you want to work around those restrictions (don't get me started on the reason why these restrictions are there in the first place if you can download an equivalent library without issue).
Also if I am using the second approach then why do I still have to add Bouncy Castle as a security provider. If I do not do so then I get a "No Such Provider" exception (...) ?
The Bouncy Castle PGP functionality is actually build upon the JCA; it's that simple. If it wasn't you could not use Java keys or other (platform or hardware) cryptographic functionality.
A lot of other software components also assume the JCA to be used. You cannot simply plug the lightweight API into an existing protocol implementation.

encrypt files at rest, properly

I have just watched a crypto 101 talk which said if you are typing the letters "AES" into your code, you're doing it wrong! The solution was to "just use GPG".
If you are storing your data on the cloud, all readers and writers need to know the key. If the key is a public private key, that's just a slow key but not a more secure key than just having a good password?
What standard alternatives are there to GPG that properly encrypt data at rest but use a shared secret instead of public keys?
I use Java, and would like to use a library, but want interchange with other platforms.
The solution is wrong in terms - you don't use "GPG" but OpenPGP.
Indeed for encryption using shared secrets (passphrases and alike) OpenPGP is optimal, as it supports multiple methods at the same time and includes compression.
The alternative would be to use CMS encryption with keypairs derived (in some predetermined way) from the shared secret. However such scheme is not standard.
I can remember also XML encryption that supports encryption with symmetric keys, but it has certain security flaws.
So OpenPGP is probably the best way to go.
Regarding compatibility - OpenPGP-compliant library should create packets that can be later processed by any other OpenPGP-compliant library or application. Unfortunately OpenPGP implementation in popular BouncyCastle library sometimes produces not compliant packets - we came across its issues several times when packets created with BouncyCastle could not be processed by GnuPG or our SecureBlackbox due to issues in the packet created.

How to convert between PGP keyrings and Java keystore files?

I am currently working on an Android app that talks to a server process on a remote machine. The installation packages for both the Android client and server need to be cryptographically signed; the Android client with a Java Keystore File (JKS) and the server with a PGP key from a keyring file. If possible, I would like to reduce the dependencies by signing both packages with the same key, but neither signing tool supports the opposite file format.
Is it possible to convert a PGP keyring file into a JKS file? Or alternatively, is it possible to convert a JKS file into a PGP keyring file? If so, how?
Edit for clarification: The idea here is to use a single cryptographic key as input for two different signing tools. The tools do not know about each other; it's just some random key to them. I do not want to sign an Android package with PGP, or the server installation package with Android's signing tool, as either would make the output unreadable to the end user.
While it might be theoretically possible there are certainly no tools to do that. If you would want to write one yourself there are a lot of hurdles to overcome. On a low level view there are many different ways to sign data (even if you restrict yourself to RSA, there are still many standards and parameters to choose from). On a high level view such key files and their front end abstractions of certificates or simply "keys" on the pgp side contain a lot meta information like a validity period, ownership information and so on. If you could actually deal with the low crypto problems then you still have to define some translation from one set of meta data to the other.
Also from a cryptographic point of view any key reuse is strongly frowned upon. There are many ways typically sound primitives can break apart if they are used in an unintended way. Certainly the authors and implementers of the algorithms behind the Android tools and the PGP tools did not imagine their tools to be used with such cross generated keys.

Java PKCS11 Standard for Crypto tokens

Hello I am trying to make an applet in Java which reads Smart Cards ( as Security Tokens) and I didn't manage to handle it at all. I already found this :http://docs.oracle.com/javase/6/docs/technotes/guides/security/SunProviders.html#SunPKCS11Provider which should give me some details... but I have never added a provider in Java ... and I also can't find any of the classes mentioned there for the provider...
Thank you.
You shouldn't need to reference the provider directly. You ask the API for a particular algorithm and it finds the appropriate provider. PKCS#11 is quirky, though. You'll have to read the detailed doc very carefully. I strongly recommend writing the app to do something with a software provider first. For example, create a Java Keystore, create a key in it and sign it then verify the signature. Definitely write a positive and negative test case. In other words, show that tampering with the data makes the verification fail. Next, figure out how to use the PKCS#11 provider by changing your program to use it. Using the Java cryptography APIs is hard enough without adding all the complications of PKCS#11 and your specific smart card to the mix.

Categories

Resources