How to wrap Microsoft RSA key blob in HSM

2.1k Views Asked by At

I have a requirement to wrap an RSAPrivateKey in an HSM, such that it can be sent off to a Microsoft CA for key archival and I'm not sure what approach to take.

The issue is that the Microsoft RSA key format is proprietary and doesn't seem to be supported by either pkcs11 or the nCipher HSM my company uses.

http://msdn.microsoft.com/en-us/library/cc250013.aspx

If this were just an RSAPrivateKey it would be straightforward to generate the key pair in the HSM, load the wrapping key in the HSM, wrap the RSAPrivateKey and extract the wrapped key bytes. Obviously since this key blob format isn't supported I need to take a different approach.

My first thought was to extend RSAPrivateKey and override getEncoded() method to return this proprietary key format. I'm using the IAIK pkcs11 wrapper that provides a high-level API to pkcs11 in Java and there is some support for creating vendor-defined key types. However, the interface for vendor-defined keys seems to exist only as a convenience to extend the built-in key types in client code and doesn't actually allow one to modify the key encoding within the HSM.

The second idea was to use a pkcs11 data object and simply treat that as the key blob and then encrypt that with the wrapping key. The same problem here is that in order to copy the private key bytes into the data object, it seems that I need to extract the private key bytes into the application code and then create the data object from there, which defeats the entire point of having the keys in the HSM.

I'm looking for alternatives to these approaches or perhaps there's some feature in pkcs11 I've overlooked that would allow me to do this? Any insight would be appreciated.

3

There are 3 best solutions below

2
On

If this is an unsupported proprietary format you may have to run proprietary code within the HSM to accomplish this. Many HSM's allow you to run proprietary code, but you will need support from the HSM provider to be able to load the code in the first place. Furthermore, running your own code in a HSM could break security certification (FIPS or Common Criteria).

Otherwise you will have to retrieve the private key from the HSM, put it into the correct format within a secured environment, and wrap it using the normal encryption facilities of the HSM. This will of course expose the private key outside the HSM.

You could also ask Microsoft if they have a preferred solution.

2
On

I agree this looks like a data format not supported by the nShield HSMs (might be worth double-checking that with the support team, though).

Assuming this is the case, there is only one way to do this securely - one has to use a much lower-level API to load the private key and pass it to some bespoke code running within the HSM (making use of the CodeSafe technology), which would expose the key material, translate it into the necessary format and wrap it with the wrapping key.

Any other approach will result in key exposure on the host. Plus, if you've generated your key with sensible (default) permissions, you can't expose the key anyway without writing bespoke code that utilises your Administrator Card Set.

I would suggest you contact the support team about the issue. You might even get through to some friendly consultants, cough, who could help you with this.

1
On

What you probably want to do is using a PKCS#11 wrapper. I am a little confused wheter you are interacting with the HSM from within Java (since you mention IAIK or .Net since you want to export to a Microsoft RSAPrivateKey). Anyway a PKCS11 wrapper (IAIK for Java, NCryptoki for .Net) will allow you to communicate with the HSM using PKCS#11 v2.30, make sure to check supported version in your wrapper and HSM specifications as there might be incompatibilities between versions.

PKCS#11 allows you to generate an RSA key pair within your HSM using the C_GenerateKeyPair function. You will have to specify a Mechanism (RSA_PKCS_KEY_PAIR_GEN) and provide two templates, one for the private key and one for the public key. Make sure that the CKA_WRAP attribute for the private key is set to true.

To load the wrapping key in the HSM the function C_CreateObject can be used in combination with a template.

You could then used the C_WrapKey function to wrap the Private RSA key with the key you imported into the HSM. First use the C_FindObjectsInit, C_FindObjects and C_FindObjectsFinal to retrieve handles to the key to be wrapped and the wrapping key. Then call the C_WrapKey function with the appropriate Mechanism and the two handles.