PGP Encryption with Mule ESB
Recently I encounter an encryption problem in Mule ESB that surprised
me...I could not figure out how to encrypt a message?!?! I wasn't able
to find an example on how PGP "encryption" should be configured even
after numerous google and mule forum searches. I was getting a little
concerned that the PGP support in mule may be for decryption only. The PGP Security documentation
shows how to setup a security filter to decrypt messages but no example
for encrypting (that may change soon...more on that later). I finally posted a question on the mule forum and got some help from the community.
First of all, I should of been looking at the transformers in mule to perform encryption...duh! I was so focused on trying to get the security filter to encrypt messages that I forgot about transformers...I know it's hard to image :) I found out the there is an <encrypt-transformer> and was a little embarrassed that I didn't find it before. So, I configured the <encrypt-transformer> to use the <pgp:keybased-encryption-strategy> just like I did for the security filter per the PGP Security documentation. I thought "wow, that was easy", ran my configuration and got a NullPointerException. :(
I could see in the stacktrace that the problem was in the KeyBasedEncryptionStrategy, which was surprising because I was referencing the same <pgp:keybased-encryption-strategy> configuration in the security filter and that was working fine. Then after taking a closer look at the security filter configuration I noticed that I was missing a reference to the credentialsAccessor. The problem I was faced with is how to configured the <encrypt-transformer> to use the credentialsAccessor I was using? Spring to the rescue! The solution is quite simple. Basically, all I had to do was inject the credentialsAccessor into the KeyBasedEncryptionStrategy. To do that I had to configure a new spring bean (id="keyBEStrategy" below) and inject my keyManager and credentialsAccessor. The nice thing about this solution is that the <encrypt-transformer> can still be used as is with just referencing the newly created strategy (i.e., strategy-ref="keyBEStrategy"). Here's an example configuration:
<?xml version="1.0"?>This workaround is pretty clean. MuleSoft is going to review the solution and possibly update their documentation accordingly.
<file:connector name="fileConnector" pollingFrequency="10000" streaming="false" autoDelete="true">
<spring:bean id="pgpKeyManager" class="org.mule.module.pgp.PGPKeyRingImpl" init-method="initialise">
<spring:property name="publicKeyRingFileName" value="<path to public keyring>/pubring.gpg"/>
<spring:property name="secretKeyRingFileName" value="<path to private keyring>/secring.gpg"/>
<!-- secretAliasId is the public key -->
<spring:property name="secretAliasId" value="<public key id"/>
<spring:property name="secretPassphrase" value="<password>"/>
<spring:bean id="keyBEStrategy" class="org.mule.module.pgp.KeyBasedEncryptionStrategy"
<spring:property name="keyManager" ref="pgpKeyManager"/>
<spring:property name="credentialsAccessor" ref="credentialAccessor"/>
<pgp:security-provider name="pgpSecurityProvider" keyManager-ref="pgpKeyManager"/>
<spring:bean id="credentialAccessor" class="org.mule.module.pgp.FakeCredentialAccessor"/>
<file:outbound-endpoint connector-ref="fileConnector" path="./encrypted"
<encrypt-transformer name="pgpEncrypt" strategy-ref="keyBEStrategy"/>