-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Description
I have been working on PGP Encryption/Decryption in Java with a bouncy castle API for a while and I had success working with files, but I have a requirement to work with inputStream/byte array and I am having issues doing that. With the following code, encryption is working without any issues. But for decryption, I m having the "Invalid Armor" error, see the error message below. I have searched and I couldn't find similar errors anywhere.. Let me know what I need to fix in my code. I am also using the PGPUtil class to convert/read public and private keys.
Error:
Encryption Success
Exception in thread "main" java.io.IOException: invalid armor
at org.bouncycastle.bcpg.ArmoredInputStream.readIgnoreSpace(Unknown Source)
at org.bouncycastle.bcpg.ArmoredInputStream.read(Unknown Source)
at org.bouncycastle.bcpg.BCPGInputStream.nextPacketTag(Unknown Source)
at org.bouncycastle.openpgp.PGPObjectFactory.nextObject(Unknown Source)
at com.iice.vega.unity.api.batch.pgp.PGPProcess.decrypt(PGPProcess.java:63)
at com.iice.vega.unity.api.batch.pgp.PGPTest.main(PGPTest.java:64)
Here is my code:
public class PGPProcess {
private static String publicKeyPath = System.getProperty("user.dir")+"/keys/Public_Key.asc";
private static String privateKeyPath = System.getProperty("user.dir")+"/keys/Private_Key.asc";
private static String password = "";
public static byte[] decrypt(byte[] encrypted)
throws IOException, PGPException, NoSuchProviderException {
Security.addProvider(new BouncyCastleProvider());
InputStream keyIn = new BufferedInputStream(new FileInputStream(stsPrivateKeyPath));
char[] password = "".toCharArray();
InputStream in = new ByteArrayInputStream(encrypted);
in = PGPUtil.getDecoderStream(in);
JcaPGPObjectFactory pgpF = new JcaPGPObjectFactory(in);
PGPEncryptedDataList enc;
Object o = pgpF.nextObject();
if (o instanceof PGPEncryptedDataList) {
enc = (PGPEncryptedDataList) o;
} else {
enc = (PGPEncryptedDataList) pgpF.nextObject();
}
Iterator it = enc.getEncryptedDataObjects();
PGPPrivateKey sKey = null;
PGPPublicKeyEncryptedData pbe = null;
PGPSecretKeyRingCollection pgpSec = new PGPSecretKeyRingCollection(
PGPUtil.getDecoderStream(keyIn), new JcaKeyFingerprintCalculator());
while (sKey == null && it.hasNext()) {
pbe = (PGPPublicKeyEncryptedData) it.next();
sKey = PGPExampleUtil.findSecretKey(pgpSec, pbe.getKeyID(), password);
}
if (sKey == null) {
throw new IllegalArgumentException(
"secret key for message not found.");
}
InputStream clear = pbe.getDataStream(new JcePublicKeyDataDecryptorFactoryBuilder().setProvider("BC").build(sKey));
JcaPGPObjectFactory plainFact = new JcaPGPObjectFactory(clear);
PGPCompressedData cData = (PGPCompressedData)plainFact.nextObject();
JcaPGPObjectFactory pgpFact = new JcaPGPObjectFactory(cData.getDataStream());
PGPLiteralData ld = (PGPLiteralData) pgpFact.nextObject();
InputStream unc = ld.getInputStream();
ByteArrayOutputStream out = new ByteArrayOutputStream();
int ch;
while ((ch = unc.read()) >= 0) {
out.write(ch);
}
byte[] returnBytes = out.toByteArray();
out.close();
return returnBytes;
}
public static byte[] encrypt(byte[] clearData)
throws IOException, PGPException, NoSuchProviderException {
Security.addProvider(new BouncyCastleProvider());
String fileName=null;
boolean withIntegrityCheck =true;
boolean armor = false;
if (fileName == null) {
fileName = PGPLiteralData.CONSOLE;
}
PGPPublicKey encKey = PGPExampleUtil.readPublicKey(stsPublicKeyPath);
ByteArrayOutputStream encOut = new ByteArrayOutputStream();
OutputStream out = encOut;
if (armor) {
out = new ArmoredOutputStream(out);
}
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
PGPCompressedDataGenerator comData = new PGPCompressedDataGenerator(
PGPCompressedData.ZIP);
OutputStream cos = comData.open(bOut); // open it with the final
// destination
PGPLiteralDataGenerator lData = new PGPLiteralDataGenerator();
OutputStream pOut = lData.open(cos, // the compressed output stream
PGPLiteralData.BINARY, fileName, // "filename" to store
clearData.length, // length of clear data
new Date() // current time
);
pOut.write(clearData);
lData.close();
comData.close();
PGPEncryptedDataGenerator cPk = new PGPEncryptedDataGenerator(new JcePGPDataEncryptorBuilder(PGPEncryptedData.CAST5).setWithIntegrityPacket(withIntegrityCheck).setSecureRandom(new SecureRandom()).setProvider("BC"));
cPk.addMethod(new JcePublicKeyKeyEncryptionMethodGenerator(encKey).setProvider("BC"));
byte[] bytes = bOut.toByteArray();
OutputStream cOut = cPk.open(out, bytes.length);
cOut.write(bytes); // obtain the actual bytes from the compressed stream
cOut.close();
out.close();
return encOut.toByteArray();
}
}