bc-java icon indicating copy to clipboard operation
bc-java copied to clipboard

`JcaPGPKeyConverter` incompatible with Thales JCA `LunaProvider` and RSA key pair generation

Open scordio opened this issue 1 month ago • 2 comments

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

scordio avatar Nov 10 '25 17:11 scordio

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.

dghgit avatar Nov 12 '25 21:11 dghgit

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.

vanitasvitae avatar Nov 28 '25 12:11 vanitasvitae