`JcaPGPKeyConverter` incompatible with Thales JCA `LunaProvider` and RSA key pair generation
I'm working with a Thales Luna Network HSM and would like to use its LunaProvider as the implementation for JcaOpenPGPKeyGenerator.
When trying to generate an RSA key pair with the following:
OpenPGPKey key = new JcaOpenPGPKeyGenerator(4, LunaProvider.getInstance())
.withPrimaryKey(generator -> generator.generateRsaKeyPair(4096))
.build()
it fails with:
com.safenetinc.luna.exception.LunaException: Cannot access sensitive attributes...
at com.safenetinc.luna.provider.key.LunaPrivateKeyRsa.getPrivateExponent(LunaPrivateKeyRsa.java:37)
at org.bouncycastle.openpgp.operator.jcajce.JcaPGPKeyConverter.getPrivateBCPGKey(Unknown Source)
at org.bouncycastle.openpgp.operator.jcajce.JcaPGPKeyConverter.getPGPPrivateKey(Unknown Source)
at org.bouncycastle.openpgp.operator.jcajce.JcaPGPKeyPair.getPrivateKey(Unknown Source)
at org.bouncycastle.openpgp.operator.jcajce.JcaPGPKeyPair.<init>(Unknown Source)
at org.bouncycastle.openpgp.operator.jcajce.JcaPGPKeyPairGeneratorProvider$JcaPGPKeyPairGenerator.generateRsaKeyPair(Unknown Source)
at org.bouncycastle.openpgp.operator.PGPKeyPairGenerator.generateRsaKeyPair(Unknown Source)
at <lambda>
...
This is because LunaPrivateKeyRsa throws a new LunaException("Cannot access sensitive attributes...") in all methods exposing sensitive parts of the key:
getCrtCoefficient()getPrimeExponentP()getPrimeExponentQ()getPrimeP()getPrimeQ()getPrivateExponent()
and JcaPGPKeyConverter calls some of them at:
https://github.com/bcgit/bc-java/blob/444055ed8cb635a82910891355681481f1ad615f/pg/src/main/java/org/bouncycastle/openpgp/operator/jcajce/JcaPGPKeyConverter.java#L647
Dependencies
- com.safenet-inc:luna-provider:10.4.1-7 (not available on Maven Central)
- org.bouncycastle:bcpg-jdk18on:1.82
It's a HSM key, it's not going to provide the information required to produce a PGP encoding. Try using JcaPGPPrivateKey directly, you'll need to calculate the keyID for the public key as but you should be able to do that using the converter.
it's not going to provide the information required to produce a PGP encoding.
That's not totally correct.
Regarding HSM/TPM keys, I'm considering adding support for https://www.ietf.org/archive/id/draft-dkg-openpgp-hardware-secrets-02.html
With this protocol extension it would be possible to create secret key packets which do not contain actual secret key material. Instead, the secret key packet would hint that the private key is stored on some hardware device.
There is a chance that the OpenPGP WG might adopt the draft for an official RFC.
GnuPG already has a similar mechanism (GNU_DUMMY_S2K) that is already present in BC, although not yet utilized. Adding hardware key support to BC requires some smaller changes, which I'm currently exploring.