I answer my question in the hope that this will help someone else in the queue, since the answer to this question is VERY hard to find anywhere on the Internet.
In versions of McAfee E-Business Server prior to 8.6, there was a compatibility issue with PGP BouncyCastle, and most people seemed to be unable to get it working. Therefore, if your supplier / client / bank uses the version of E-Business Server up to 8.6, you may well be SOL and you may need to find another encryption package.
Source: https://kc.mcafee.com/corporate/index?page=content&id=KB60816&cat=CORP_EBUSINESS_SERVER&actp=LIST
"Decrypting a file that has been encrypted with Bouncy Castle v1.37 may result in an Access Violation Error (or SIGSEG on UNIX). This issue was in this release."
Fortunately, our bank uses McAfee E-Business Server 8.6. However, this is only part of the equation. To solve the incompatibility problem, we had to disable BOTH and ASCII compression before they could successfully decrypt and verify our file. Therefore, using the source code that I published, you call it that for clients using E-Business Server 8.6:
PGPService.signAndEncrypt(clearTextFileName, secureFileName, privKeyIn, privateKeyFilePassword, pubKeyIn, true, false, false);
Of course, this means that you cannot use ASCII reservations, which may or may not be a problem with you. If so, David on the BouncyCastle dev mailing list suggested you use BouncyCastle in non-packet mode. IE: Do not pass a byte buffer to open commands in a stream. Or write and encrypt the file in two passes.
For example, calling:
public static void signFile(String fileNameIn, String fileNameOut, InputStream privKeyIn, String password, boolean armoredOutput) { OutputStream out = null; BCPGOutputStream bOut = null; OutputStream lOut = null; InputStream fIn = null; try { out = new FileOutputStream(fileNameOut); if (armoredOutput) { out = new ArmoredOutputStream(out); } PGPSecretKey pgpSec = readSecretKey(privKeyIn); PGPPrivateKey pgpPrivKey = pgpSec.extractPrivateKey(password.toCharArray(), "BC"); PGPSignatureGenerator sGen = new PGPSignatureGenerator(pgpSec.getPublicKey().getAlgorithm(), PGPUtil.SHA1, "BC"); sGen.initSign(PGPSignature.BINARY_DOCUMENT, pgpPrivKey); Iterator it = pgpSec.getPublicKey().getUserIDs(); if (it.hasNext()) { PGPSignatureSubpacketGenerator spGen = new PGPSignatureSubpacketGenerator(); spGen.setSignerUserID(false, (String)it.next()); sGen.setHashedSubpackets(spGen.generate()); } PGPCompressedDataGenerator cGen = new PGPCompressedDataGenerator(PGPCompressedData.ZLIB); bOut = new BCPGOutputStream(cGen.open(out)); sGen.generateOnePassVersion(false).encode(bOut); File file = new File(fileNameIn); PGPLiteralDataGenerator lGen = new PGPLiteralDataGenerator(); lOut = lGen.open(bOut, PGPLiteralData.BINARY, file); fIn = new FileInputStream(file); int ch = 0; while ((ch = fIn.read()) >= 0) { lOut.write(ch); sGen.update((byte) ch); } lGen.close(); sGen.generate().encode(bOut); cGen.close(); } catch (Exception e) { log.error(e); throw new RuntimeException(e); } finally { if (lOut != null) try { lOut.close(); } catch (IOException e) {} if (bOut != null) try { bOut.close(); } catch (IOException e) {} if (out != null) try { out.close(); } catch (IOException e) {} if (fIn != null) try { fIn.close(); } catch (IOException e) {} } }
The following is a call:
public static byte[] encrypt(byte[] data, InputStream pubKeyIn, boolean isPublicKeyArmored) { FileOutputStream fos = null; BufferedReader isr = null; try { if (isPublicKeyArmored) pubKeyIn = new ArmoredInputStream(pubKeyIn); PGPPublicKey key = readPublicKeyFromCol(pubKeyIn); log.info("Creating a temp file..."); // Create a file and write the string to it. File tempfile = File.createTempFile("pgp", null); fos = new FileOutputStream(tempfile); fos.write(data); fos.close(); log.info("Temp file created at: " + tempfile.getAbsolutePath()); log.info("Reading the temp file to make sure that the bits were written...\n"); isr = new BufferedReader(new FileReader(tempfile)); String line = ""; while ((line = isr.readLine()) != null ) { log.info(line + "\n"); } int count = 0; for (java.util.Iterator iterator = key.getUserIDs(); iterator.hasNext();) { count++; log.info(iterator.next()); } log.info("Key Count = " + count); // Encrypt the data. ByteArrayOutputStream baos = new ByteArrayOutputStream(); _encrypt(tempfile.getAbsolutePath(), baos, key); log.info("Encrypted text length = " + baos.size()); tempfile.delete(); return baos.toByteArray(); } catch (PGPException e) { log.error(e); throw new RuntimeException(e); } catch (Exception e) { log.error(e); throw new RuntimeException(e); } finally { if (fos != null) try { fos.close(); } catch (IOException e) {} if (isr != null) try { isr.close(); } catch (IOException e) {} } }
Caution emptor, as I have not been able to test this method to make sure that this even solves the incompatibility problem. But this is a way you can try if you have no options, and use ASCII reservations for the E-Business Server recipient.
More information can be found in the BouncyCastle dev mailing list archive, which can help if you decide to go this route. Specifically, this thread: http://www.bouncycastle.org/devmailarchive/msg12080.html