mirrored from https://www.bouncycastle.org/repositories/bc-java
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Open
Description
I'm generating PGP v6 keys with BouncyCastle 1.82, but OpenPGP.js v6.3.0 fails to validate the self-signature when trying to use the key for encryption.
Key generation code (Java):
public class PGPKeyPairGenerator {
public static final int DEFAULT_KEY_SIZE = 4096;
public static final int HASH_ALGORITHM = HashAlgorithmTags.SHA256;
public static final int ENCRYPTION_ALGORITHM = SymmetricKeyAlgorithmTags.AES_256;
private static final BigInteger PUBLIC_EXPONENT = new BigInteger("65537");
private static final int CERTAINTY = 128;
private static final int PGP_VERSION = 6;
static {
BouncyCastleProvider provider = new BouncyCastleProvider();
String name = provider.getName();
synchronized (Security.class) {
Security.removeProvider(name); // remove old instance
Security.addProvider(provider);
}
}
private String pass_phrase;
private PGPSecretKey pgp_secret_key;
public PGPKeyPairGenerator(
final String user_id
, final String pass_phrase
) throws NoSuchAlgorithmException, PGPException {
this.pass_phrase = pass_phrase;
PGPKeyPair pgp_key_pair =
new BcPGPKeyPair(
PGP_VERSION
, PGPPublicKey.RSA_GENERAL
, generate_rsa_key_pair()
, new Date()
);
PGPDigestCalculator digest_calculator = create_digest_calculator();
this.pgp_secret_key = new PGPSecretKey(
PGPSignature.DEFAULT_CERTIFICATION
, pgp_key_pair
, user_id
, digest_calculator
, null
, null
, create_content_signer(pgp_key_pair.getPublicKey().getAlgorithm())
, create_encryptor()
);
}
private PBESecretKeyEncryptor create_encryptor() {
return
new JcePBESecretKeyEncryptorBuilder(ENCRYPTION_ALGORITHM)
.setProvider(BouncyCastleProvider.PROVIDER_NAME)
.build(pass_phrase.toCharArray());
}
private AsymmetricCipherKeyPair generate_rsa_key_pair() {
RSAKeyPairGenerator generator = new RSAKeyPairGenerator();
generator.init(
new RSAKeyGenerationParameters(
PUBLIC_EXPONENT
, new SecureRandom()
, DEFAULT_KEY_SIZE
, CERTAINTY
)
);
return generator.generateKeyPair();
}
private PGPDigestCalculator create_digest_calculator() throws PGPException {
return new JcaPGPDigestCalculatorProviderBuilder()
.setProvider(BouncyCastleProvider.PROVIDER_NAME)
.build()
.get(HashAlgorithmTags.SHA1);
}
private JcaPGPContentSignerBuilder create_content_signer(int algorithm) {
return new JcaPGPContentSignerBuilder(algorithm, HASH_ALGORITHM)
.setProvider(BouncyCastleProvider.PROVIDER_NAME);
}
public PGPPublicKey getPublicKey() {
return this.pgp_secret_key.getPublicKey();
}
public PGPPrivateKey getPrivateKey() throws PGPException {
PBESecretKeyDecryptor desc = new JcePBESecretKeyDecryptorBuilder()
.setProvider(BouncyCastleProvider.PROVIDER_NAME).build(
this.pass_phrase.toCharArray());
return this.pgp_secret_key.extractPrivateKey(desc);
}
public void getAsciiArmoredPublicKey(OutputStream stream)
throws IOException {
ArmoredOutputStream aos_private_key = new ArmoredOutputStream(stream);
aos_private_key.write(this.pgp_secret_key.getPublicKey().getEncoded());
aos_private_key.flush();
aos_private_key.close();
stream.flush();
}
public void getAsciiArmoredPrivateKey(OutputStream stream)
throws IOException {
ArmoredOutputStream aosPrivateKey = new ArmoredOutputStream(stream);
aosPrivateKey.write(this.pgp_secret_key.getEncoded());
aosPrivateKey.flush();
aosPrivateKey.close();
stream.flush();
}
}Generated public key (armored):
-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: BCPG v1.82
mQIRBmlmYpQBAAACBxAAxrWzjfk5xI597kuUlD20D8wWMlcfq9/++MmWTFWImuOH
BPeqVSIUZDvlLLQ+ICgSqrpnPJUXt1BLNE5VS+XlXs7y1vLuYXOJWPCAyNmjlIs9
vgC3qePkeCxaK3FITggQ0vrMlxet65awAiOJkuNXoqZGYBVKJAcNd41DwPwQ2/cl
ibxGw29W6l/601Qu9Eb4sxtvtILENnwwyo2Dt7fJvgdEQAxO5X9ELhkvZ06g2ILN
XnOEeBxcBHJaO3Pt3l68npX19jqvs9gk0brn3fzCFhdl9uQD+qGoJJB6VUWY9/1D
wM/YHF9CAolIAcCkHGivMca5sIhpp/01EZDY4QBHm5im2RGckUNVfMhmPUygK+v/
NsWwOUXj0hbnkLfDzWxbCX4N8XNbwa+ca0utxRuQurTqXkn6pbxriTfXLmZEdgAY
Kxz7ejf0IZG1rVE/gunxtYrravXG0O1Ml1iTTh8P8RQ8kqs/LFgVrCZBGRsD9n8L
Jdon8u1jNctdxR/XXAwLd6l2dcLrshYlkcagZ4iowfsWziQ4PsezDMG9N2eVH3Wm
ZX4nviii/BmLSBZsVR75l2CdXCdDeoHM9lpJUACJd2TbV2J5hYfDMRWdDJmeC1zN
hq4Wd/2YP7IsPxCjz6uP6vwR0RaTkUXR4yTBZg/XwENweqj0Y2zGCYSwE+GOT/8A
EQEAAbQEY2lhb8LBlwYQAQgAAAA2IqEG5MM9p7wXkr3uSikEIdogobP/SR20Jn3r
2xO5O3KqxKcFgmlmYpQCGw8EFQoJCAQLCQgHAAAAAPSAEKCZP5qxCO5qLkhNBt6M
7wcP/iA+cDnFDzwT4m5LVXrmRlbl/eBcU5CpjzX9FrSGQKXimVgkDl8XPqp4i/q3
Zm+C6QWvVHsMOdGx76jpnxl0J7e3bhNTi6mlmS22oeskfD4VLfdPeewJK4rsurMJ
5c8o8a20KdntMKtC/qhVQBwB5/B1EFScIBxXt8uYYdPsgIL9xhdnuu38kGE/xjpT
NUUFVqrU5bmBA80WAMOUto+I52FxdpJ+AcKV20xGghNlDGPuP9Ae0pzJ1+nzmZkO
wx8rvCSL4eJ3P4ENSuuYaDivw2y1TN61oVMXlu1rFq7/u22WGzijpOcUuka6rjXM
zn9OxVuMY8W/GJQV2lkO8znvpjlL74Eb8wduSBcVzAlgr7QZJvBtCsCzggd+pxgi
x3QCSwQXqQqRVXMSZ5iszvOt4ZklH0FccBpLtk25UeplN5TRD+pV6xe53MzIAlyW
5BzPnlkcS0hwaDhtyxnW0Mv4QghhsEwlEJ+6tM0ey23bTq3ChKP+jpxV6HG7Hs/5
O3SdhC5YcZt8PFJjFb1bipwADdOAAhhfTghjJh1ARl+HN4LecSvhnZsp8Ca5vw2R
seqBH+y3xRjgR9lvP2fhHUO157Jh3auEi0OEM2lSTuU0xp3NDjsKEfcP54FbmuXM
WQnIYvGsj6TpYaOORVagmcFxldaNRj6jr8FC80pmCyjzzqC9
=KoGb
-----END PGP PUBLIC KEY BLOCK-----
Error from OpenPGP.js:
Error: Could not find valid key signature in key e4c33da7bc1792bd
Context:
- The same code works fine with PGP_VERSION = 4
- OpenPGP.js v6 claims RFC 9580 (v6) support
- I also opened an issue on the OpenPGP.js repo: issue
Questions:
- Has BouncyCastle's PGP v6 implementation been tested for interoperability with other RFC 9580 implementations?
- Are there any known differences in how BC generates v6 self-signatures compared to the RFC 9580 spec?
- Is there something missing in my key generation code (e.g., required subpackets for v6 keys)?
Metadata
Metadata
Assignees
Labels
No labels