Skip to content

Instantly share code, notes, and snippets.

@vanitasvitae
Created July 11, 2018 18:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vanitasvitae/e125fe669a0e57ccf2420f3e7d59d24f to your computer and use it in GitHub Desktop.
Save vanitasvitae/e125fe669a0e57ccf2420f3e7d59d24f to your computer and use it in GitHub Desktop.
package org.pgpainless.pgpainless;
import static junit.framework.TestCase.assertNotNull;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.security.InvalidAlgorithmParameterException;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.Security;
import java.util.Date;
import java.util.Iterator;
import org.bouncycastle.bcpg.CompressionAlgorithmTags;
import org.bouncycastle.bcpg.HashAlgorithmTags;
import org.bouncycastle.bcpg.PublicKeyAlgorithmTags;
import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags;
import org.bouncycastle.bcpg.sig.Features;
import org.bouncycastle.bcpg.sig.KeyFlags;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.jce.spec.ECNamedCurveGenParameterSpec;
import org.bouncycastle.openpgp.PGPException;
import org.bouncycastle.openpgp.PGPKeyPair;
import org.bouncycastle.openpgp.PGPKeyRingGenerator;
import org.bouncycastle.openpgp.PGPPublicKey;
import org.bouncycastle.openpgp.PGPPublicKeyRing;
import org.bouncycastle.openpgp.PGPSecretKeyRing;
import org.bouncycastle.openpgp.PGPSignature;
import org.bouncycastle.openpgp.PGPSignatureSubpacketGenerator;
import org.bouncycastle.openpgp.operator.PGPContentSignerBuilder;
import org.bouncycastle.openpgp.operator.PGPDigestCalculator;
import org.bouncycastle.openpgp.operator.bc.BcKeyFingerprintCalculator;
import org.bouncycastle.openpgp.operator.jcajce.JcaPGPContentSignerBuilder;
import org.bouncycastle.openpgp.operator.jcajce.JcaPGPDigestCalculatorProviderBuilder;
import org.bouncycastle.openpgp.operator.jcajce.JcaPGPKeyPair;
import org.junit.Test;
public class BouncycastleExportSubkeys {
@Test
public void testExportImport() throws NoSuchAlgorithmException, NoSuchProviderException, InvalidAlgorithmParameterException, PGPException, IOException {
Security.addProvider(new BouncyCastleProvider());
KeyPairGenerator generator;
KeyPair pair;
// Generate master key
generator = KeyPairGenerator.getInstance("ECDSA", BouncyCastleProvider.PROVIDER_NAME);
generator.initialize(new ECNamedCurveGenParameterSpec("P-256"));
pair = generator.generateKeyPair();
PGPKeyPair pgpMasterKey = new JcaPGPKeyPair(PublicKeyAlgorithmTags.ECDSA, pair, new Date());
PGPSignatureSubpacketGenerator subPackets = new PGPSignatureSubpacketGenerator();
subPackets.setKeyFlags(false, KeyFlags.AUTHENTICATION & KeyFlags.CERTIFY_OTHER & KeyFlags.SIGN_DATA);
subPackets.setPreferredCompressionAlgorithms(false, new int[] {
SymmetricKeyAlgorithmTags.AES_256,
SymmetricKeyAlgorithmTags.AES_128,
SymmetricKeyAlgorithmTags.AES_128});
subPackets.setPreferredHashAlgorithms(false, new int[] {
HashAlgorithmTags.SHA512,
HashAlgorithmTags.SHA384,
HashAlgorithmTags.SHA256,
HashAlgorithmTags.SHA224});
subPackets.setPreferredCompressionAlgorithms(false, new int[] {
CompressionAlgorithmTags.ZLIB,
CompressionAlgorithmTags.BZIP2,
CompressionAlgorithmTags.ZIP,
CompressionAlgorithmTags.UNCOMPRESSED});
subPackets.setFeature(false, Features.FEATURE_MODIFICATION_DETECTION);
// Generate sub key
generator = KeyPairGenerator.getInstance("ECDH", BouncyCastleProvider.PROVIDER_NAME);
generator.initialize(new ECNamedCurveGenParameterSpec("P-256"));
pair = generator.generateKeyPair();
PGPKeyPair pgpSubKey = new JcaPGPKeyPair(PublicKeyAlgorithmTags.ECDH, pair, new Date());
// Assemble key
PGPDigestCalculator calculator = new JcaPGPDigestCalculatorProviderBuilder()
.setProvider(BouncyCastleProvider.PROVIDER_NAME)
.build()
.get(HashAlgorithmTags.SHA1);
PGPContentSignerBuilder signerBuilder = new JcaPGPContentSignerBuilder(
pgpMasterKey.getPublicKey().getAlgorithm(), HashAlgorithmTags.SHA512)
.setProvider(BouncyCastleProvider.PROVIDER_NAME);
PGPKeyRingGenerator pgpGenerator = new PGPKeyRingGenerator(PGPSignature.POSITIVE_CERTIFICATION,
pgpMasterKey, "alice@wonderland.lit", calculator, subPackets.generate(), null,
signerBuilder, null);
// Add sub key
subPackets.setKeyFlags(false, KeyFlags.ENCRYPT_STORAGE & KeyFlags.ENCRYPT_COMMS);
pgpGenerator.addSubKey(pgpSubKey, subPackets.generate(), null);
// Generate SecretKeyRing
PGPSecretKeyRing secretKeys = pgpGenerator.generateSecretKeyRing();
// I know, the below is possible, but I cannot access that method in my case
// PGPPublicKeyRing publicKeys = pgpGenerator.generatePublicKeyRing();
// Extract the public keys
ByteArrayOutputStream outputStream = new ByteArrayOutputStream(2048);
Iterator<PGPPublicKey> iterator = secretKeys.getPublicKeys();
while (iterator.hasNext()) {
outputStream.write(iterator.next().getEncoded());
}
PGPPublicKeyRing publicKeys = new PGPPublicKeyRing(outputStream.toByteArray(), new BcKeyFingerprintCalculator());
// Check, if all public keys made it to the new public key ring (they don't)
iterator = secretKeys.getPublicKeys();
while (iterator.hasNext()) {
assertNotNull(publicKeys.getPublicKey(iterator.next().getKeyID()));
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment