{"id":582,"date":"2004-04-01T08:48:15","date_gmt":"2004-04-01T12:48:15","guid":{"rendered":"http:\/\/wordpress.cephas.net\/?p=582"},"modified":"2020-05-27T09:18:03","modified_gmt":"2020-05-27T17:18:03","slug":"pgp-encryption-using-bouncy-castle","status":"publish","type":"post","link":"https:\/\/cephas.net\/blog\/2004\/04\/01\/pgp-encryption-using-bouncy-castle\/","title":{"rendered":"PGP Encryption using Bouncy Castle"},"content":{"rendered":"<p>It can&#8217;t be that hard.  So given a couple hours of hacking with the library, here&#8217;s a fully illustrated example that shows how to encrypt a file using the Bouncy Castle Cryptography API and PGP. First, giving credit where credit is due, the example comes mostly from the KeyBasedFileProcessor example that ships with the Bouncy Castle PGP libraries. You can find it in the \/src\/org\/bouncycastle\/openpgp\/examples directory if you download the source.  I&#8217;ve simply unpacked the example a little, providing some pretty pictures and explanation of what the various pieces are.<\/p>\n<p>As in any example, you need to have downloaded a couple libraries; in this case you need to visit <a href=\"http:\/\/www.bouncycastle.org\/latest_releases.html\">http:\/\/www.bouncycastle.org\/latest_releases.html<\/a> and download the <a href=\"http:\/\/www.bouncycastle.org\/download\/bcprov-jdk14-122.jar\">bcprov-jdk14-122<\/a> and <a href=\"http:\/\/www.bouncycastle.org\/download\/bcpg-jdk14-122.jar\">bcpg-jdk14-122<\/a> jar files.  Add those to your project, as in this example, simply make sure to add them to the classpath when running the example from the command line.<\/p>\n<p>Next, while you don&#8217;t need to have PGP installed, you do need to have a at least one public keyring file available on your system. I&#8217;m using PGP 6.5.8 on Windows which automatically saves my public keyring for me. You can find the location of the keyring file by Edit &#8211;&gt; Options &#8211;&gt; Files from within the PGP Keys window. You should see something like this:<br \/>\n<a href=\"\/images\/misc\/pgp_options.gif\"><img src=\"\/images\/misc\/pgp_options_small.gif\" border=\"0\" alt=\"PGP Options\" vspace=\"4\" hspace=\"4\" align=\"center\"><\/a><br \/>\nNote the location of the Public Keyring File.<\/p>\n<p>Second, you&#8217;ll need to generate a keypair (if you don&#8217;t already have one). I won&#8217;t go into the how or why (I assume you know the how and why) but you do need to make sure that you create what the Bouncy Castle folks call a &#8216;RSA key&#8217; or &#8216;El Gamal key&#8217; (<a href=\"http:\/\/article.gmane.org\/gmane.comp.encryption.bouncy-castle.devel\/224\">source<\/a>) rather than a DSA key.  If you try to use a DSA keypair (which I&#8217;m assuming is synonomous with Diffie-Hellman\/DSS?), that I ran into:<br \/>\n<code>org.bouncycastle.openpgp.PGPException: Can't use DSA for encryption<\/code>, which again is explained by the link above.<\/p>\n<p>Now that you downloaded the appropriate libraries, created an RSA keypair and located your public keyring file, we&#8217;re ready to start.  Open up your favorite Java IDE (I&#8217;m using Eclipse) and start by importing the appropriate libraries:<br \/>\n<code><br \/>\nimport java.io.*;<br \/>\nimport java.security.*;<br \/>\nimport org.bouncycastle.bcpg.*;<br \/>\nimport org.bouncycastle.jce.provider.*;<br \/>\nimport org.bouncycastle.openpgp.*;<br \/>\n<\/code><br \/>\nI took a shortcut above and didn&#8217;t specify exactly what classes I wanted to import for clarity, if you&#8217;re using Eclipse you can easily clean that up by selecting Source &#8211;&gt; Organize Imports (or by downloading the source code at the end of this example).  Next the class declaration and the standard public static void main etc.. The KeyBasedFileProcessor example on the BouncyCastle website lets you pass in the location of the public keyring and the file you want to encrypt, I&#8217;m hardcoding it in my code so that it&#8217;s crystal clear what everything is:<br \/>\n<code><br \/>\n\/\/ the keyring that holds the public key we're encrypting with<br \/>\nString publicKeyFilePath = \"C:\\\\pgp6.5.8\\\\pubring.pkr\";<br \/>\n<\/code><br \/>\nand then use the static addProvider() method of the java.security.Security class:<br \/>\n<code><br \/>\nSecurity.addProvider(new BouncyCastleProvider());<br \/>\n<\/code><br \/>\nNext I chose to create a temporary file to hold the message that I want to encrypt:<br \/>\n<code><br \/>\nFile outputfile = File.createTempFile(\"pgp\", null);<br \/>\nFileWriter writer = new FileWriter(outputfile);<br \/>\nwriter.write(\"the message I want to encrypt\".toCharArray());<br \/>\nwriter.close();<br \/>\n<\/code><br \/>\nRead the public keyring file into a FileInputStream and then call the readPublicKey() method that was provided for us by the KeyBasedFileProcessor:<br \/>\n<code><br \/>\nFileInputStream\tin = new FileInputStream(publicKeyFilePath);<br \/>\nPGPPublicKey key = readPublicKey(in);<br \/>\n<\/code><br \/>\nAt this point it&#8217;s important to note that the PGPPublicKeyRing class (at least in the version I was using) appears to have a bug where it only recognizes the first key in the keyring.  If you use the getUserIds() method of the object returned you&#8217;ll only see one key:<br \/>\n<code><br \/>\nfor (java.util.Iterator iterator = key.getUserIDs(); iterator.hasNext();) {<br \/>\n\tSystem.out.println((String)iterator.next());<br \/>\n}<br \/>\n<\/code><br \/>\nThis could cause you problems if you have multiple keys in your keyring and if the first key is not an RSA or El Gamal key.  <\/p>\n<p>Finally, create an armored ASCII text file and call the encryptFile() method (again provided us by the KeyBasedFileProcessor example:<br \/>\n<code><br \/>\nFileOutputStream out = new FileOutputStream(outputfile.getAbsolutePath() + \".asc\");<br \/>\n\/\/ (file we want to encrypt, file to write encrypted text to, public key)<br \/>\nencryptFile(outputfile.getAbsolutePath(), out, key);<br \/>\n<\/code><br \/>\nThe rest of the example is almost verbatim from the KeyBaseFileProcessor example, I&#8217;ll paste the code here, but I didn&#8217;t do much to it:<br \/>\n<code><br \/>\nout = new ArmoredOutputStream(out);<br \/>\nByteArrayOutputStream bOut = new ByteArrayOutputStream();<br \/>\nPGPCompressedDataGenerator comData = new PGPCompressedDataGenerator(PGPCompressedDataGenerator.ZIP);<br \/>\nPGPUtil.writeFileToLiteralData(comData.open(bOut), PGPLiteralData.BINARY, new File(fileName));<br \/>\ncomData.close();<br \/>\nPGPEncryptedDataGenerator cPk = new PGPEncryptedDataGenerator(PGPEncryptedDataGenerator.CAST5, new SecureRandom(), \"BC\");<br \/>\ncPk.addMethod(encKey);<br \/>\nbyte[] bytes = bOut.toByteArray();<br \/>\nOutputStream cOut = cPk.open(out, bytes.length);<br \/>\ncOut.write(bytes);<br \/>\ncPk.close();<br \/>\nout.close();<br \/>\n<\/code><br \/>\nOne last thing that I gleamed from their web-based forum was that one of the exceptions thrown by the above code is a PGPException, which itself doesn&#8217;t tell you much (in my case it was simply saying <code>exception encrypting session key<\/code>.  PGPException can be a wrapper for an underlying exception though, and you should use the getUnderlyingException() method to determine what the real cause of the problem is (which lead me to the <code>Can't use DSA for encryption<\/code> message that I mentioned above).<\/p>\n<p>You can download the source code and batch file for the example above here:<\/p>\n<p><a href=\"\/images\/files\/bouncy_castle_pgp_example.zip\">bouncy_castle_pgp_example.zip<\/a><\/p>\n<p><font color='red'>Updated 04\/07\/2004: David Hook wrote to let me know that there is a bug in the examples, I updated both the sample code above and the zip file that contains the full source code.  Look at the <a href=\"http:\/\/www.bouncycastle.org\/betas\">beta versions<\/a> for the updated examples.<\/font><\/p>\n","protected":false},"excerpt":{"rendered":"<p>It can&#8217;t be that hard. So given a couple hours of hacking with the library, here&#8217;s a fully illustrated example that shows how to encrypt a file using the Bouncy Castle Cryptography API and PGP. First, giving credit where credit is due, the example comes mostly from the KeyBasedFileProcessor example that ships with the Bouncy &hellip; <a href=\"https:\/\/cephas.net\/blog\/2004\/04\/01\/pgp-encryption-using-bouncy-castle\/\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">PGP Encryption using Bouncy Castle<\/span> <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[3,2,12],"tags":[],"_links":{"self":[{"href":"https:\/\/cephas.net\/blog\/wp-json\/wp\/v2\/posts\/582"}],"collection":[{"href":"https:\/\/cephas.net\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/cephas.net\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/cephas.net\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/cephas.net\/blog\/wp-json\/wp\/v2\/comments?post=582"}],"version-history":[{"count":3,"href":"https:\/\/cephas.net\/blog\/wp-json\/wp\/v2\/posts\/582\/revisions"}],"predecessor-version":[{"id":3057,"href":"https:\/\/cephas.net\/blog\/wp-json\/wp\/v2\/posts\/582\/revisions\/3057"}],"wp:attachment":[{"href":"https:\/\/cephas.net\/blog\/wp-json\/wp\/v2\/media?parent=582"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/cephas.net\/blog\/wp-json\/wp\/v2\/categories?post=582"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/cephas.net\/blog\/wp-json\/wp\/v2\/tags?post=582"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}