mirror of
https://github.com/pgpainless/pgpainless.git
synced 2024-12-24 03:47:57 +01:00
Add examples for key generation and parsing
This commit is contained in:
parent
41b8d15cec
commit
0958915b4c
2 changed files with 395 additions and 0 deletions
|
@ -0,0 +1,220 @@
|
|||
/*
|
||||
* Copyright 2021 Paul Schaub.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.pgpainless.example;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.security.InvalidAlgorithmParameterException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
import org.bouncycastle.openpgp.PGPException;
|
||||
import org.bouncycastle.openpgp.PGPPublicKeyRing;
|
||||
import org.bouncycastle.openpgp.PGPSecretKeyRing;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.pgpainless.PGPainless;
|
||||
import org.pgpainless.algorithm.CompressionAlgorithm;
|
||||
import org.pgpainless.algorithm.EncryptionPurpose;
|
||||
import org.pgpainless.algorithm.Feature;
|
||||
import org.pgpainless.algorithm.HashAlgorithm;
|
||||
import org.pgpainless.algorithm.KeyFlag;
|
||||
import org.pgpainless.algorithm.PublicKeyAlgorithm;
|
||||
import org.pgpainless.algorithm.SymmetricKeyAlgorithm;
|
||||
import org.pgpainless.key.generation.KeySpec;
|
||||
import org.pgpainless.key.generation.type.KeyType;
|
||||
import org.pgpainless.key.generation.type.ecc.EllipticCurve;
|
||||
import org.pgpainless.key.generation.type.eddsa.EdDSACurve;
|
||||
import org.pgpainless.key.generation.type.rsa.RsaLength;
|
||||
import org.pgpainless.key.info.KeyRingInfo;
|
||||
import org.pgpainless.key.util.KeyRingUtils;
|
||||
import org.pgpainless.key.util.UserId;
|
||||
import org.pgpainless.util.ArmorUtils;
|
||||
import org.pgpainless.util.Passphrase;
|
||||
|
||||
/**
|
||||
* This class demonstrates how to use PGPainless to generate secret keys.
|
||||
* In general the starting point for generating secret keys using PGPainless is {@link PGPainless#generateKeyRing()}.
|
||||
* The result ({@link org.pgpainless.key.generation.KeyRingBuilder}) provides some factory methods for key archetypes
|
||||
* such as {@link org.pgpainless.key.generation.KeyRingBuilder#modernKeyRing(String, String)} or
|
||||
* {@link org.pgpainless.key.generation.KeyRingBuilder#simpleRsaKeyRing(String, RsaLength)}.
|
||||
*
|
||||
* Those methods always take a user-id which is used as primary user-id, as well as a passphrase which is used to encrypt
|
||||
* the secret key.
|
||||
* To generate unencrypted secret keys, just pass {@code null} as passphrase.
|
||||
*
|
||||
* Besides the archetype methods, it is possible to generate fully customized keys (see {@link #generateCustomOpenPGPKey()}).
|
||||
*/
|
||||
public class GenerateKeys {
|
||||
|
||||
/**
|
||||
* This example demonstrates how to generate a modern OpenPGP key which consists of an ed25519 EdDSA primary key
|
||||
* used solely for certification of subkeys, as well as an ed25519 EdDSA signing subkey, and an X25519 ECDH
|
||||
* encryption subkey.
|
||||
*
|
||||
* This is the recommended way to generate OpenPGP keys with PGPainless.
|
||||
*
|
||||
* @throws PGPException
|
||||
* @throws InvalidAlgorithmParameterException
|
||||
* @throws NoSuchAlgorithmException
|
||||
*/
|
||||
@Test
|
||||
public void generateModernEcKey() throws PGPException, InvalidAlgorithmParameterException, NoSuchAlgorithmException, IOException {
|
||||
// Define a primary user-id
|
||||
String userId = "gbaker@pgpainless.org";
|
||||
// Set a password to protect the secret key
|
||||
String password = "ra1nb0w";
|
||||
// Generate the OpenPGP key
|
||||
PGPSecretKeyRing secretKey = PGPainless.generateKeyRing()
|
||||
.modernKeyRing(userId, password);
|
||||
// Extract public key
|
||||
PGPPublicKeyRing publicKey = KeyRingUtils.publicKeyRingFrom(secretKey);
|
||||
// Encode the public key to an ASCII armored string ready for sharing
|
||||
String asciiArmoredPublicKey = ArmorUtils.toAsciiArmoredString(publicKey);
|
||||
|
||||
|
||||
KeyRingInfo keyInfo = new KeyRingInfo(secretKey);
|
||||
assertEquals(3, keyInfo.getSecretKeys().size());
|
||||
assertEquals(userId, keyInfo.getPrimaryUserId());
|
||||
assertEquals(PublicKeyAlgorithm.EDDSA.getAlgorithmId(),
|
||||
keyInfo.getPublicKey().getAlgorithm());
|
||||
assertEquals(PublicKeyAlgorithm.EDDSA.getAlgorithmId(),
|
||||
keyInfo.getSigningSubkeys().get(0).getAlgorithm());
|
||||
assertEquals(PublicKeyAlgorithm.ECDH.getAlgorithmId(),
|
||||
keyInfo.getEncryptionSubkeys(EncryptionPurpose.STORAGE_AND_COMMUNICATIONS).get(0).getAlgorithm());
|
||||
}
|
||||
|
||||
/**
|
||||
* This example demonstrates how to generate a simple OpenPGP key consisting of a 4096 bit RSA key.
|
||||
* The RSA key is used for both signing and certifying, as well as encryption.
|
||||
*
|
||||
* This method is recommended if the application has to deal with legacy clients with poor algorithm support.
|
||||
*
|
||||
* @throws PGPException
|
||||
* @throws InvalidAlgorithmParameterException
|
||||
* @throws NoSuchAlgorithmException
|
||||
*/
|
||||
@Test
|
||||
public void generateSimpleRSAKey() throws PGPException, InvalidAlgorithmParameterException, NoSuchAlgorithmException {
|
||||
// Define a primary user-id
|
||||
String userId = "mpage@pgpainless.org";
|
||||
// Set a password to protect the secret key
|
||||
String password = "b1angl3s";
|
||||
// Generate the OpenPGP key
|
||||
PGPSecretKeyRing secretKey = PGPainless.generateKeyRing()
|
||||
.simpleRsaKeyRing(userId, RsaLength._4096, password);
|
||||
|
||||
|
||||
KeyRingInfo keyInfo = new KeyRingInfo(secretKey);
|
||||
assertEquals(1, keyInfo.getSecretKeys().size());
|
||||
assertEquals(userId, keyInfo.getPrimaryUserId());
|
||||
assertEquals(PublicKeyAlgorithm.RSA_GENERAL.getAlgorithmId(), keyInfo.getPublicKey().getAlgorithm());
|
||||
}
|
||||
|
||||
/**
|
||||
* This example demonstrates how to generate a simple OpenPGP key based on elliptic curves.
|
||||
* The key consists of an ECDSA primary key that is used both for certification of subkeys, as well as signing of data,
|
||||
* and a single ECDH encryption subkey.
|
||||
*
|
||||
* This method is recommended if small keys and high performance are desired.
|
||||
*
|
||||
* @throws PGPException
|
||||
* @throws InvalidAlgorithmParameterException
|
||||
* @throws NoSuchAlgorithmException
|
||||
*/
|
||||
@Test
|
||||
public void generateSimpleECKey() throws PGPException, InvalidAlgorithmParameterException, NoSuchAlgorithmException {
|
||||
String userId = "mhelms@pgpainless.org";
|
||||
String password = "tr4ns";
|
||||
|
||||
PGPSecretKeyRing secretKey = PGPainless.generateKeyRing()
|
||||
.simpleEcKeyRing(userId, password);
|
||||
|
||||
|
||||
KeyRingInfo keyInfo = new KeyRingInfo(secretKey);
|
||||
assertEquals(2, keyInfo.getSecretKeys().size());
|
||||
assertEquals(userId, keyInfo.getPrimaryUserId());
|
||||
}
|
||||
|
||||
/**
|
||||
* This example demonstrates how to generate a custom OpenPGP secret key.
|
||||
* Among user-id and password, the user can add an arbitrary number of subkeys and specify their algorithms and
|
||||
* algorithm preferences.
|
||||
*
|
||||
* @throws PGPException
|
||||
* @throws InvalidAlgorithmParameterException
|
||||
* @throws NoSuchAlgorithmException
|
||||
*/
|
||||
@Test
|
||||
public void generateCustomOpenPGPKey() throws PGPException, InvalidAlgorithmParameterException, NoSuchAlgorithmException {
|
||||
// Instead of providing a string, we can assemble a user-id by using the user-id builder.
|
||||
// The example below corresponds to "Morgan Carpenter (Pride!) <mcarpenter@pgpainless.org>"
|
||||
UserId userId = UserId.newBuilder()
|
||||
.withName("Morgan Carpenter")
|
||||
.withEmail("mcarpenter@pgpainless.org")
|
||||
.withComment("Pride!")
|
||||
.build();
|
||||
|
||||
// It is recommended to use the Passphrase class, as it can be used to safely invalidate passwords from memory
|
||||
Passphrase passphrase = Passphrase.fromPassword("1nters3x");
|
||||
|
||||
PGPSecretKeyRing secretKey = PGPainless.generateKeyRing()
|
||||
// Add the first subkey (in this case encryption)
|
||||
.withSubKey(
|
||||
KeySpec.getBuilder(
|
||||
// We choose an ECDH key over the brainpoolp256r1 curve
|
||||
KeyType.ECDH(EllipticCurve._BRAINPOOLP256R1)
|
||||
)
|
||||
// Our key can encrypt both communication data, as well as data at rest
|
||||
.withKeyFlags(KeyFlag.ENCRYPT_STORAGE, KeyFlag.ENCRYPT_COMMS)
|
||||
// Optionally: Configure the subkey with custom algorithm preferences
|
||||
// Is is recommended though to go with PGPainless' defaults which can be found in the
|
||||
// AlgorithmSuite class.
|
||||
.withDetailedConfiguration()
|
||||
.withPreferredSymmetricAlgorithms(SymmetricKeyAlgorithm.AES_256, SymmetricKeyAlgorithm.AES_192, SymmetricKeyAlgorithm.AES_128)
|
||||
.withPreferredHashAlgorithms(HashAlgorithm.SHA512, HashAlgorithm.SHA384, HashAlgorithm.SHA256)
|
||||
.withPreferredCompressionAlgorithms(CompressionAlgorithm.ZIP, CompressionAlgorithm.BZIP2, CompressionAlgorithm.ZLIB)
|
||||
// Modification Detection is highly recommended
|
||||
.withFeature(Feature.MODIFICATION_DETECTION)
|
||||
.done()
|
||||
)
|
||||
// Add the second subkey (signing)
|
||||
.withSubKey(
|
||||
KeySpec.getBuilder(
|
||||
KeyType.ECDSA(EllipticCurve._BRAINPOOLP384R1)
|
||||
)
|
||||
// This key is used for creating signatures only
|
||||
.withKeyFlags(KeyFlag.SIGN_DATA)
|
||||
// Instead of manually specifying algorithm preferences, we can simply use PGPainless' sane defaults
|
||||
.withDefaultAlgorithms()
|
||||
)
|
||||
// Lastly we add the primary key (certification only in our case)
|
||||
.withPrimaryKey(
|
||||
KeySpec.getBuilder(KeyType.EDDSA(EdDSACurve._Ed25519))
|
||||
// The primary key MUST carry the CERTIFY_OTHER flag, but CAN carry additional flags
|
||||
.withKeyFlags(KeyFlag.CERTIFY_OTHER)
|
||||
.withDefaultAlgorithms()
|
||||
)
|
||||
.withPrimaryUserId(userId)
|
||||
.withPassphrase(passphrase)
|
||||
.build();
|
||||
|
||||
|
||||
KeyRingInfo keyInfo = new KeyRingInfo(secretKey);
|
||||
assertEquals(3, keyInfo.getSecretKeys().size());
|
||||
assertEquals("Morgan Carpenter (Pride!) <mcarpenter@pgpainless.org>", keyInfo.getPrimaryUserId());
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,175 @@
|
|||
/*
|
||||
* Copyright 2021 Paul Schaub.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.pgpainless.example;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.bouncycastle.openpgp.PGPException;
|
||||
import org.bouncycastle.openpgp.PGPPublicKeyRing;
|
||||
import org.bouncycastle.openpgp.PGPPublicKeyRingCollection;
|
||||
import org.bouncycastle.openpgp.PGPSecretKeyRing;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.pgpainless.PGPainless;
|
||||
import org.pgpainless.key.OpenPgpV4Fingerprint;
|
||||
import org.pgpainless.key.info.KeyRingInfo;
|
||||
|
||||
public class ReadKeys {
|
||||
|
||||
/**
|
||||
* This example demonstrates how to parse a public key (certificate) from an ASCII armored string.
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
@Test
|
||||
public void readCertificate() throws IOException {
|
||||
String certificate = "" +
|
||||
"-----BEGIN PGP PUBLIC KEY BLOCK-----\n" +
|
||||
"Comment: Alice's OpenPGP certificate\n" +
|
||||
"\n" +
|
||||
"mDMEXEcE6RYJKwYBBAHaRw8BAQdArjWwk3FAqyiFbFBKT4TzXcVBqPTB3gmzlC/U\n" +
|
||||
"b7O1u120JkFsaWNlIExvdmVsYWNlIDxhbGljZUBvcGVucGdwLmV4YW1wbGU+iJAE\n" +
|
||||
"ExYIADgCGwMFCwkIBwIGFQoJCAsCBBYCAwECHgECF4AWIQTrhbtfozp14V6UTmPy\n" +
|
||||
"MVUMT0fjjgUCXaWfOgAKCRDyMVUMT0fjjukrAPoDnHBSogOmsHOsd9qGsiZpgRnO\n" +
|
||||
"dypvbm+QtXZqth9rvwD9HcDC0tC+PHAsO7OTh1S1TC9RiJsvawAfCPaQZoed8gK4\n" +
|
||||
"OARcRwTpEgorBgEEAZdVAQUBAQdAQv8GIa2rSTzgqbXCpDDYMiKRVitCsy203x3s\n" +
|
||||
"E9+eviIDAQgHiHgEGBYIACAWIQTrhbtfozp14V6UTmPyMVUMT0fjjgUCXEcE6QIb\n" +
|
||||
"DAAKCRDyMVUMT0fjjlnQAQDFHUs6TIcxrNTtEZFjUFm1M0PJ1Dng/cDW4xN80fsn\n" +
|
||||
"0QEA22Kr7VkCjeAEC08VSTeV+QFsmz55/lntWkwYWhmvOgE=\n" +
|
||||
"=iIGO\n" +
|
||||
"-----END PGP PUBLIC KEY BLOCK-----";
|
||||
|
||||
PGPPublicKeyRing publicKey = PGPainless.readKeyRing()
|
||||
.publicKeyRing(certificate);
|
||||
|
||||
|
||||
KeyRingInfo keyInfo = new KeyRingInfo(publicKey);
|
||||
OpenPgpV4Fingerprint fingerprint = new OpenPgpV4Fingerprint("EB85 BB5F A33A 75E1 5E94 4E63 F231 550C 4F47 E38E");
|
||||
assertEquals(fingerprint, keyInfo.getFingerprint());
|
||||
assertEquals("Alice Lovelace <alice@openpgp.example>", keyInfo.getPrimaryUserId());
|
||||
}
|
||||
|
||||
/**
|
||||
* This example demonstrates how to parse an ASCII armored secret key.
|
||||
*
|
||||
* @throws PGPException
|
||||
* @throws IOException
|
||||
*/
|
||||
@Test
|
||||
public void readSecretKey() throws PGPException, IOException {
|
||||
String key = "\n" +
|
||||
"-----BEGIN PGP PRIVATE KEY BLOCK-----\n" +
|
||||
"Comment: Alice's OpenPGP Transferable Secret Key\n" +
|
||||
"\n" +
|
||||
"lFgEXEcE6RYJKwYBBAHaRw8BAQdArjWwk3FAqyiFbFBKT4TzXcVBqPTB3gmzlC/U\n" +
|
||||
"b7O1u10AAP9XBeW6lzGOLx7zHH9AsUDUTb2pggYGMzd0P3ulJ2AfvQ4RtCZBbGlj\n" +
|
||||
"ZSBMb3ZlbGFjZSA8YWxpY2VAb3BlbnBncC5leGFtcGxlPoiQBBMWCAA4AhsDBQsJ\n" +
|
||||
"CAcCBhUKCQgLAgQWAgMBAh4BAheAFiEE64W7X6M6deFelE5j8jFVDE9H444FAl2l\n" +
|
||||
"nzoACgkQ8jFVDE9H447pKwD6A5xwUqIDprBzrHfahrImaYEZzncqb25vkLV2arYf\n" +
|
||||
"a78A/R3AwtLQvjxwLDuzk4dUtUwvUYibL2sAHwj2kGaHnfICnF0EXEcE6RIKKwYB\n" +
|
||||
"BAGXVQEFAQEHQEL/BiGtq0k84Km1wqQw2DIikVYrQrMttN8d7BPfnr4iAwEIBwAA\n" +
|
||||
"/3/xFPG6U17rhTuq+07gmEvaFYKfxRB6sgAYiW6TMTpQEK6IeAQYFggAIBYhBOuF\n" +
|
||||
"u1+jOnXhXpROY/IxVQxPR+OOBQJcRwTpAhsMAAoJEPIxVQxPR+OOWdABAMUdSzpM\n" +
|
||||
"hzGs1O0RkWNQWbUzQ8nUOeD9wNbjE3zR+yfRAQDbYqvtWQKN4AQLTxVJN5X5AWyb\n" +
|
||||
"Pnn+We1aTBhaGa86AQ==\n" +
|
||||
"=n8OM\n" +
|
||||
"-----END PGP PRIVATE KEY BLOCK-----";
|
||||
|
||||
PGPSecretKeyRing secretKey = PGPainless.readKeyRing()
|
||||
.secretKeyRing(key);
|
||||
|
||||
|
||||
KeyRingInfo keyInfo = new KeyRingInfo(secretKey);
|
||||
OpenPgpV4Fingerprint fingerprint = new OpenPgpV4Fingerprint("EB85 BB5F A33A 75E1 5E94 4E63 F231 550C 4F47 E38E");
|
||||
assertEquals(fingerprint, keyInfo.getFingerprint());
|
||||
assertEquals("Alice Lovelace <alice@openpgp.example>", keyInfo.getPrimaryUserId());
|
||||
}
|
||||
|
||||
/**
|
||||
* This example demonstrates how to read a collection of multiple OpenPGP public keys (certificates) at once.
|
||||
*
|
||||
* Note, that a public key collection can both be a concatenation of public key blocks (like below),
|
||||
* as well as a single public key block containing multiple public key packets.
|
||||
*
|
||||
* @throws PGPException
|
||||
* @throws IOException
|
||||
*/
|
||||
@Test
|
||||
public void readKeyRingCollection() throws PGPException, IOException {
|
||||
String certificateCollection = "-----BEGIN PGP PUBLIC KEY BLOCK-----\n" +
|
||||
"Comment: Alice's OpenPGP certificate\n" +
|
||||
"\n" +
|
||||
"mDMEXEcE6RYJKwYBBAHaRw8BAQdArjWwk3FAqyiFbFBKT4TzXcVBqPTB3gmzlC/U\n" +
|
||||
"b7O1u120JkFsaWNlIExvdmVsYWNlIDxhbGljZUBvcGVucGdwLmV4YW1wbGU+iJAE\n" +
|
||||
"ExYIADgCGwMFCwkIBwIGFQoJCAsCBBYCAwECHgECF4AWIQTrhbtfozp14V6UTmPy\n" +
|
||||
"MVUMT0fjjgUCXaWfOgAKCRDyMVUMT0fjjukrAPoDnHBSogOmsHOsd9qGsiZpgRnO\n" +
|
||||
"dypvbm+QtXZqth9rvwD9HcDC0tC+PHAsO7OTh1S1TC9RiJsvawAfCPaQZoed8gK4\n" +
|
||||
"OARcRwTpEgorBgEEAZdVAQUBAQdAQv8GIa2rSTzgqbXCpDDYMiKRVitCsy203x3s\n" +
|
||||
"E9+eviIDAQgHiHgEGBYIACAWIQTrhbtfozp14V6UTmPyMVUMT0fjjgUCXEcE6QIb\n" +
|
||||
"DAAKCRDyMVUMT0fjjlnQAQDFHUs6TIcxrNTtEZFjUFm1M0PJ1Dng/cDW4xN80fsn\n" +
|
||||
"0QEA22Kr7VkCjeAEC08VSTeV+QFsmz55/lntWkwYWhmvOgE=\n" +
|
||||
"=iIGO\n" +
|
||||
"-----END PGP PUBLIC KEY BLOCK-----" +
|
||||
"\n" +
|
||||
"-----BEGIN PGP PUBLIC KEY BLOCK-----\n" +
|
||||
"Comment: Bob's OpenPGP certificate\n" +
|
||||
"\n" +
|
||||
"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\n" +
|
||||
"NEJd3XZRzaXZE2aAMQ==\n" +
|
||||
"=NXei\n" +
|
||||
"-----END PGP PUBLIC KEY BLOCK-----";
|
||||
|
||||
PGPPublicKeyRingCollection collection = PGPainless.readKeyRing()
|
||||
.publicKeyRingCollection(certificateCollection);
|
||||
assertEquals(2, collection.size());
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue