Я отвечаю на свой вопрос в надежде, что это поможет кому-то еще, поскольку ответ на этот вопрос ОЧЕНЬ трудно найти где-либо в Интернете.
В версиях McAfee E-Business Server до 8.6 была проблема совместимости с BouncyCastle PGP, и, похоже, большинство людей не смогли заставить его работать. Поэтому, если ваш поставщик / клиент / банк использует версию E-Business Server до 8.6, вы вполне можете быть SOL и вам может понадобиться найти другой пакет шифрования.
Источник: https://kc.mcafee.com/corporate/index?page=content&id=KB60816&cat=CORP_EBUSINESS_SERVER&actp=LIST
"Расшифровка файла, который был зашифрован
с Bouncy Castle v1.37 может привести к
Ошибка нарушения доступа (или SIGSEG на
Платформы UNIX). Эта проблема была
адресовано в этом выпуске. "
К счастью, наш банк использует McAfee E-Business Server 8.6. Однако это только часть уравнения. Чтобы решить проблему несовместимости, нам пришлось отключить ОБА сжатие и защиту ASCII, прежде чем они смогли успешно расшифровать и проверить наш файл. Таким образом, используя исходный код, который я разместил, вы можете назвать его для клиентов, использующих E-Business Server 8.6:
PGPService.signAndEncrypt(clearTextFileName, secureFileName, privKeyIn, privateKeyFilePassword, pubKeyIn, true, false, false);
Конечно, это означает, что вы не можете использовать защиту ASCII, что может быть или не быть проблемой с вами. Если да, то Дэвид в списке рассылки разработчиков BouncyCastle предложил использовать BouncyCastle в непакетном режиме. IE: не передавать байтовый буфер в команды open в потоке. Или подпишите и зашифруйте файл в два прохода.
Например, по телефону:
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) {}
}
}
После звонка:
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) {}
}
}
Caveat emptor, так как я не смог протестировать этот метод, чтобы посмотреть, решит ли он проблему несовместимости. Но это путь, который вы можете попробовать, если у вас нет выбора и вы должны использовать защиту ASCII для назначения E-Business Server.
Дополнительная информация может быть найдена в архиве списка рассылки разработчика BouncyCastle, который может помочь, если вы решите пойти по этому пути. Конкретно эта тема: http://www.bouncycastle.org/devmailarchive/msg12080.html