Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to derive a key with JCA/JCE and with an HSM

Tags:

java

jce

hsm

I have a master key in an HSM and I want to derive it with a given diversifier. I am quite new to JCA/JCE, and a bit lost with KeyGenerator, SecretKeyFactory, ... especially since all parameters are strings. I want to use AES or HmacSha1. It seems I need to use a SecretKeyFactory, and provide a KeySpecs. But which type of KeySpecs?

(I have seen a post on that topic, but I didn't seem an HSM was used.)

Thanks.

like image 943
Joel Avatar asked Oct 09 '14 15:10

Joel


People also ask

How is JCA different from JCE?

The basic difference between JCA and JCE is that JCE is an extension of JCA, not a replacement. The JCA includes classes like MessageDigest , SecureRandom , KeyFactory , Signature and KeyStore . JCE add some more classes of cryptography like Cipher , KeyGeneration , Mac and KeyGeneration .

What is JCA name?

Java Cryptography Architecture (JCA) Reference Guide.

What is JCE provider?

The AWS CloudHSM JCE provider is a provider implementation built from the Java Cryptographic Extension (JCE) provider framework. The JCE provides a framework for performing cryptographic operations using the Java Development Kit (JDK).


1 Answers

You can derive key using:

  • password-based derivation (PKCS#5) as described in Deriving a secret from a master key using JCE/JCA or
  • emulate C_Derive from PKCS#11 using encryption as described in PKCS11 deriveKey() and encrypt() returning different results for 3DES

to use HSM from JCA/JCE APIs, you need to add the corresponding provider to the JCA/JCE APIs and then specify the the provider parameter to request for that specific provider implementation.

For example:

int slot = 0;
Provider provider = new au.com.safenet.crypto.provider.SAFENETProvider(slot);
Security.addProvider(provider);
final String PROVIDER = provider.getName(); // "SAFENET", "SAFENET.1", ...

KeyGenerator keyGen = KeyGenerator.getInstance("DESede", PROVIDER);
Key baseKey = keyGen.generateKey();

Cipher desCipher = Cipher.getInstance("DESede/CBC/PKCS5Padding", PROVIDER);
desCipher.init(Cipher.ENCRYPT_MODE, baseKey);

byte[] derived = desCipher.doFinal("diversification data".getBytes());

Note that if you need to do key derivation very often, you might consider to use your provider's PCKS#11 wrapper for Java (e.g. jcprov from SafeNet) or other APIs so that you can be more explicit about its session management and be more efficient about resource usage.

like image 172
Afriza N. Arief Avatar answered Oct 06 '22 13:10

Afriza N. Arief