For the purposes of performing a Diffie-Hellman key agreement with Curve25519
, I am generating the following key pair using BouncyCastle 1.68
:
// Generate a key pair
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("X25519", BouncyCastleProvider.PROVIDER_NAME);
keyPairGenerator.initialize(new XDHParameterSpec(XDHParameterSpec.X25519));
KeyPair keyPair = keyPairGenerator.generateKeyPair();
Using this key pair I am now successfully able to perform a key agreement:
// Perform a (dummy) key agreement
KeyAgreement keyAgreement = KeyAgreement.getInstance("X25519", BouncyCastleProvider.PROVIDER_NAME);
keyAgreement.init(keyPair.getPrivate());
keyAgreement.doPhase(keyPair.getPublic(), true);
byte[] secret = keyAgreement.generateSecret();
Now I would like to securely store this keypair in a BCFKS keystore for future use, something like this:
// Create a key store for the key pair
KeyStore keyStore = KeyStore.getInstance("BCFKS", BouncyCastleProvider.PROVIDER_NAME);
keyStore.load(null, "keyStorePassword".toCharArray());
// Put the key pair in the key store as a PrivateKeyEntry
final X509Certificate selfSignedCertificate = generateSelfSignedCertificate(keyPair); // TODO: How to generate a certificate?
final KeyStore.PrivateKeyEntry entry = new KeyStore.PrivateKeyEntry(keyPair.getPrivate(), new Certificate[]{selfSignedCertificate});
keyStore.setEntry("alias", entry, new KeyStore.PasswordProtection("keyEntryPassword".toCharArray()));
... except the KeyStore.PrivateKeyEntry
constructor expects a certificate (as opposed to a public key), and X25519
cannot by definition be used to sign a certificate. (Attempting to create a Signer using it naturally fails with java.lang.IllegalArgumentException: Unknown signature type requested: X25519
)
Am I missing something obvious here, or is there currently no simple way to put a X25519
key pair in a BCFKS
keystore?
Is there maybe a workaround I can apply, considering I don't really need a certificate, just a way to store the private/public keys in the keystore?
Java keystores cannot store a public key directly, only inside a certificate.
Instead of self-signing the
X25519
certificate (which is impossible, as the key can't be used for signing), sign it using a 2nd bogus/throwaway key (f.i. RSA).