Using a bouncy castle to create the PGP public key used by Thunderbird

I created PGP public and private keys using org.bouncycastle.openpgp.PGPKeyRingGenerator . After making the changes suggested by GregS, the public key is a .asc file, and the private key is a .skr file. I need to first distribute the public key to Thunderbird users, and then to Outlook users and other email clients. I read these instructions for getting the public key in thunderbird , but the instructions simply specify the .asc extension without specifying the contents / structure of the .asc .

How do I configure my (modified?) Code below to create a public key that can be used by remote Thunderbird users to send encrypted messages, which can then be decrypted with my private key, also generated (modified?) Code below? The accepted answer will include step-by-step instructions not only to make the necessary changes to the code below, but also to configure each remote Thunderbird user to use the prepared public key below to send emails that can be decrypted with the private key in my application created below (modified ?) code.

Here is my first key generation code project:

 import java.io.BufferedOutputStream; import java.io.FileOutputStream; import java.math.BigInteger; import java.security.SecureRandom; import java.util.Date; import org.bouncycastle.bcpg.ArmoredOutputStream; import org.bouncycastle.bcpg.HashAlgorithmTags; import org.bouncycastle.bcpg.SymmetricKeyAlgorithmTags; import org.bouncycastle.bcpg.sig.Features; import org.bouncycastle.bcpg.sig.KeyFlags; import org.bouncycastle.crypto.generators.RSAKeyPairGenerator; import org.bouncycastle.crypto.params.RSAKeyGenerationParameters; import org.bouncycastle.openpgp.PGPEncryptedData; import org.bouncycastle.openpgp.PGPKeyPair; import org.bouncycastle.openpgp.PGPPublicKeyRing; import org.bouncycastle.openpgp.PGPKeyRingGenerator; import org.bouncycastle.openpgp.PGPPublicKey; import org.bouncycastle.openpgp.PGPSecretKeyRing; import org.bouncycastle.openpgp.PGPSignature; import org.bouncycastle.openpgp.PGPSignatureSubpacketGenerator; import org.bouncycastle.openpgp.operator.PBESecretKeyEncryptor; import org.bouncycastle.openpgp.operator.PGPDigestCalculator; import org.bouncycastle.openpgp.operator.bc.BcPBESecretKeyEncryptorBuilder; import org.bouncycastle.openpgp.operator.bc.BcPGPContentSignerBuilder; import org.bouncycastle.openpgp.operator.bc.BcPGPDigestCalculatorProvider; import org.bouncycastle.openpgp.operator.bc.BcPGPKeyPair; public class RSAGen { public static void main(String args[]) throws Exception { char pass[] = {'h', 'e', 'l', 'l', 'o'}; PGPKeyRingGenerator krgen = generateKeyRingGenerator(" alice@example.com ", pass); // Generate public key ring, dump to file. PGPPublicKeyRing pkr = krgen.generatePublicKeyRing(); ArmoredOutputStream pubout = new ArmoredOutputStream(new BufferedOutputStream(new FileOutputStream("/home/user/dummy.asc"))); pkr.encode(pubout); pubout.close(); // Generate private key, dump to file. PGPSecretKeyRing skr = krgen.generateSecretKeyRing(); BufferedOutputStream secout = new BufferedOutputStream(new FileOutputStream("/home/user/dummy.skr")); skr.encode(secout); secout.close(); } public final static PGPKeyRingGenerator generateKeyRingGenerator(String id, char[] pass) throws Exception{ return generateKeyRingGenerator(id, pass, 0xc0); } // Note: s2kcount is a number between 0 and 0xff that controls the number of times to iterate the password hash before use. More // iterations are useful against offline attacks, as it takes more time to check each password. The actual number of iterations is // rather complex, and also depends on the hash function in use. Refer to Section 3.7.1.3 in rfc4880.txt. Bigger numbers give // you more iterations. As a rough rule of thumb, when using SHA256 as the hashing function, 0x10 gives you about 64 // iterations, 0x20 about 128, 0x30 about 256 and so on till 0xf0, or about 1 million iterations. The maximum you can go to is // 0xff, or about 2 million iterations. I'll use 0xc0 as a default -- about 130,000 iterations. public final static PGPKeyRingGenerator generateKeyRingGenerator(String id, char[] pass, int s2kcount) throws Exception { // This object generates individual key-pairs. RSAKeyPairGenerator kpg = new RSAKeyPairGenerator(); // Boilerplate RSA parameters, no need to change anything // except for the RSA key-size (2048). You can use whatever key-size makes sense for you -- 4096, etc. kpg.init(new RSAKeyGenerationParameters(BigInteger.valueOf(0x10001), new SecureRandom(), 2048, 12)); // First create the master (signing) key with the generator. PGPKeyPair rsakp_sign = new BcPGPKeyPair(PGPPublicKey.RSA_SIGN, kpg.generateKeyPair(), new Date()); // Then an encryption subkey. PGPKeyPair rsakp_enc = new BcPGPKeyPair(PGPPublicKey.RSA_ENCRYPT, kpg.generateKeyPair(), new Date()); // Add a self-signature on the id PGPSignatureSubpacketGenerator signhashgen = new PGPSignatureSubpacketGenerator(); // Add signed metadata on the signature. // 1) Declare its purpose signhashgen.setKeyFlags(false, KeyFlags.SIGN_DATA|KeyFlags.CERTIFY_OTHER); // 2) Set preferences for secondary crypto algorithms to use when sending messages to this key. signhashgen.setPreferredSymmetricAlgorithms (false, new int[] { SymmetricKeyAlgorithmTags.AES_256, SymmetricKeyAlgorithmTags.AES_192, SymmetricKeyAlgorithmTags.AES_128 }); signhashgen.setPreferredHashAlgorithms (false, new int[] { HashAlgorithmTags.SHA256, HashAlgorithmTags.SHA1, HashAlgorithmTags.SHA384, HashAlgorithmTags.SHA512, HashAlgorithmTags.SHA224, }); // 3) Request senders add additional checksums to the message (useful when verifying unsigned messages.) signhashgen.setFeature(false, Features.FEATURE_MODIFICATION_DETECTION); // Create a signature on the encryption subkey. PGPSignatureSubpacketGenerator enchashgen = new PGPSignatureSubpacketGenerator(); // Add metadata to declare its purpose enchashgen.setKeyFlags(false, KeyFlags.ENCRYPT_COMMS|KeyFlags.ENCRYPT_STORAGE); // Objects used to encrypt the secret key. PGPDigestCalculator sha1Calc = new BcPGPDigestCalculatorProvider().get(HashAlgorithmTags.SHA1); PGPDigestCalculator sha256Calc = new BcPGPDigestCalculatorProvider().get(HashAlgorithmTags.SHA256); // bcpg 1.48 exposes this API that includes s2kcount. Earlier versions use a default of 0x60. PBESecretKeyEncryptor pske = (new BcPBESecretKeyEncryptorBuilder(PGPEncryptedData.AES_256, sha256Calc, s2kcount)).build(pass); // Finally, create the keyring itself. The constructor takes parameters that allow it to generate the self signature. PGPKeyRingGenerator keyRingGen = new PGPKeyRingGenerator(PGPSignature.POSITIVE_CERTIFICATION, rsakp_sign, id, sha1Calc, signhashgen.generate(), null, new BcPGPContentSignerBuilder(rsakp_sign.getPublicKey().getAlgorithm(), HashAlgorithmTags.SHA1), pske); // Add our encryption subkey, together with its signature. keyRingGen.addSubKey(rsakp_enc, enchashgen.generate(), null); return keyRingGen; } } 

When I run the above code to create a .asc file and then try to import the .asc file into Thunderbird, I get the following error screen:

gpg_fail.png

Please note that I did not install GnuPG on my CentOS 7 computer.

In addition, you can easily recreate this problem on your own machine, because Thunderbird is free. You can download thunderbird this link for free . Alternatively, on my CentOS 7 machine, I downloaded Thunderbird using yum install thunderbird . You can download bouncy castle by adding the following to your pom.xml :

 <dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcpg-jdk15on</artifactId> <version>1.51</version> </dependency> 

EDIT. # 1:

To ask JRichardSnape questions, I found that maven should also automatically load the org.bouncycastle.crypto library, because it is a dependency on bcpg-jdk15on . JRichardSnape is true that RSAKeyGenerationParameters and RSAKeyPairGenerator not in the manual download bcpg-jdk15on.jar . (Note: versions in links may be inactive.) However, both classes are in maven's automated download, which is obtained from the same dependency fragment from pom.xml shown above. I say this because there are no other bouncycastle dependencies in my pom.xml . I am using Java 7.

Eclipse describes two classes imported as:

 import org.bouncycastle.crypto.params.RSAKeyGenerationParameters; import org.bouncycastle.crypto.generators.RSAKeyPairGenerator; 

I added all import statements from RSAGen.java to the code segment in my OP above. I think the problem may be due to the need for a name / signature for the key.

The following links result from this error:

Convert userId to UTF8 before creating signature # 96
non-ascii characters in name field # 92
Cannot import PGP certificate into keychain

EDIT No. 2

According to @JRichardSnape's advice, I tried Enigmail->Key management ->File ->Import keys from file . This led to the following dialog box, which appears to indicate that although the key was imported, the key was not signed. Thus, it seems that there is no name or email address associated with the imported .asc file. In addition, the key also does not appear in the EnigMail key list.

Enig_Mail_Alert.png

EDIT No. 3

Using gpg --gen-key , I was able to get the CentOS 7 terminal to create a key pair, including the public key, which I could successfully import into Thunderbird, so that Thunderbird can now associate the gpg-public key published via the terminal with the intended email recipient . But when I take all the steps to send an encrypted email from Thunderbird using a public key, the email and its attachments, however, arrive unencrypted. The steps I took to send an encrypted public key letter from a remote Thunderbird to a private key server are described in this SuperUser publication .

Given that gpg --gen-key seems to work, the main problem right now seems to be Thunderbird part of this generosity issue. In the previous paragraph, I posted great progress in resolving the Thunderbird question in the SuperUser question. Your help in answering this will be of great importance in answering this question.

EDIT # 4

I still cannot get the bouncycastle key to import into Thunderbird. However, when I use the keys created on the CentOS 7 terminal using gpg --gen-key , I can follow these steps:

 1.) I configured my Thunderbird to manage another (second) email account I have not been using. 2.) I then created a gpg key for that second account and configured encryption for that second account in Thunderbird. 3.) I sent an encrypted email containing an attachment from the first Thunderbird account to the second Thunderbird account. 4.) I was able to see that the attachment remained encrypted in the second account inbox until I used the recipient key passphrase to decrypt it. 

My CentOS 7 server still creates unencrypted attachments when I send it an email from the same "first" Thunderbird account, as described in this edit. I'm trying to determine if this is due to some kind of "automatic decryption" in dovecot / postfix / mailx / gpg on a CentOS 7 server or is it related to some settings in Thunderbird sender. I am studying this.

+6
source share
1 answer

I will try to deal with these points one by one:

Java Generation Bouncycastle Generation

Java code works and creates a useful key pair. I tested it with different email addresses and different passwords without any problems. I had a third-party by sending me an email using the public key and successfully decrypting it using the private key generated by this Java code. The key worked with the following combinations

  • Thunderbird (31.4.0) + Enigmail (1.7.2) + gpg (Gpg4win) on Windows 8
  • Thunderbird + Enigmail on ubuntu 14.10 (with desktop xfer manager)

but

The OP detects a problem with importing keys with a failure, implying the absence of a user ID in the combination CentOS / Thunderbird / pgp . Likewise, it was not imported with an error without specifying the user ID on the Windows / Outlook / Kleopatra plugin (verified, although the question specifically refers to Thunderbird).

I cannot reproduce the error - I strongly suspect that this is due either to differences in configuration or to differences in versions in GNU PG. My setup shows the following for gpg --version

 gpg (GnuPG) 2.0.26 (Gpg4win 2.2.3) libgcrypt 1.6.2 

Testing a java generated key with gpg directly

You can generate keys using java code, go to the command line and execute

 gpg --import dummy.asc 

Then the test is performed using

 gpg --edit-key alice@example.com 

verify that it has a user id by typing check at the gpg> prompt. Output Example:

 uid alice@example.com sig!3 14AEE94A 2015-02-05 [self-signature] 

If this works - you fixed the problem with gpg using the key import - check the versions of Thunderbird / Enigmail.

Using Thunderbird

It seems that most of the issues were resolved by my comment recommending importing the key through Enigmail->Key management ->File ->Import keys from file in conjunction with this related issue with OP as root.

Please note that - there is a β€œgenerate” option in the Key Management dialog box for Enigmail. If Java generation is not required, this can be used to generate key pairs - this is basically the same as generating directly via gpg, as far as I know.


The remaining problem with using Thunderbird seems to be a distrust of encryption, since the message appears in plain text on the OP server (it seems that the key should be used in a server / client combination, where clients send encrypted messages to the server).

To make sure that the message is really encrypted, I suggest changing the Enigmail parameter:

  • Enigmail β†’ Preference β†’ Sending tab
  • select "Manual encryption settings"
  • select "Always" in the "confirm before sending" field

After that, you will see an encrypted letter along with a confirmation field.

I can’t talk about how to stop your server by automatically decrypting incoming mail, since it depends on the configuration of your server and it would be better to ask as a separate question, it is possible on superuser or serverfault StackExchange sites.

PGP Email Testing

You can also review the recommendations of the Enigmail tutorial and send encrypted mail to

Adele, "Friendly Robot Email OpenPGP." Adele accepts OpenPGP messages and explanatory responses for any kind of OpenPGP message.

Address adele <at> gnupp <dot> de

+5
source

Source: https://habr.com/ru/post/981789/


All Articles