Hello,
Have doubts about the PGP Encryption by using PGP Data Format.
- We have the following code using Bouncy Castle library to sign and
encrypt the payload, given the private key and passphrase for Signing and
public key for Encryption.
- Wanted to know if we replace it with PGPDataFormat (aka Camel
Route), how can we represent the following fields:
o PGPSignature.BINARY_DOCUMENT
o PGPLiteralData.BINARY
Regards,
Arpit.
Current Legacy Code: (SECURITY_PROVIDER_NAME = BC)
public byte[] signAndEncrypt(byte[] signKey, String passphrase, byte[]
encryptionPublicKey, byte[] message) throws EncryptionException {
// final result stream.
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
PGPPublicKey encryptPublicKey =
readPublicKey(PGPUtil.getDecoderStream(new
ByteArrayInputStream(encryptionPublicKey)));
// Init encrypted data generator
PGPEncryptedDataGenerator encryptedDataGenerator = new
PGPEncryptedDataGenerator(new JcePGPDataEncryptorBuilder(PGPEncryptedData.CAST5)
.setSecureRandom(new SecureRandom())
.setProvider(SECURITY_PROVIDER_NAME));
encryptedDataGenerator.addMethod(new
JcePublicKeyKeyEncryptionMethodGenerator(encryptPublicKey));
// start compression
PGPCompressedDataGenerator compressedDataGenerator = new
PGPCompressedDataGenerator(CompressionAlgorithmTags.ZIP);
// start signature generator
PGPSecretKey pgpSecKey = readSecretKey(PGPUtil.getDecoderStream(new
ByteArrayInputStream(signKey)));
PGPPrivateKey pgpPrivKey = pgpSecKey.extractPrivateKey(new
JcePBESecretKeyDecryptorBuilder(new JcaPGPDigestCalculatorProviderBuilder()
.setProvider(SECURITY_PROVIDER_NAME).build())
.setProvider(SECURITY_PROVIDER_NAME)
.build(passphrase.toCharArray()));
PGPSignatureGenerator signatureGenerator = new PGPSignatureGenerator(
new
JcaPGPContentSignerBuilder(pgpSecKey.getPublicKey().getAlgorithm(),
HashAlgorithmTags.SHA256).setProvider(SECURITY_PROVIDER_NAME));
signatureGenerator.init(PGPSignature.BINARY_DOCUMENT, pgpPrivKey);
// iterate to find first signature to use
for (Iterator i = pgpSecKey.getPublicKey().getUserIDs(); i.hasNext();) {
String userId = (String) i.next();
PGPSignatureSubpacketGenerator spGen = new
PGPSignatureSubpacketGenerator();
spGen.setSignerUserID(false, userId);
signatureGenerator.setHashedSubpackets(spGen.generate());
// Just the first one!
break;
}
try (
//message
InputStream contentStream = new ByteArrayInputStream(message);
//out data
DataOutputStream aos = new DataOutputStream(baos);
//encrypted out
OutputStream encryptedOut = encryptedDataGenerator.open(aos, new
byte[DEFAULT_BUFFER_SIZE]);
//compressed out
OutputStream compressedOut =
compressedDataGenerator.open(encryptedOut);) {
signatureGenerator.generateOnePassVersion(false).encode(compressedOut);
// Create the Literal Data generator output stream
PGPLiteralDataGenerator literalDataGenerator = new
PGPLiteralDataGenerator();
try (
// create output stream
OutputStream literalOut = literalDataGenerator.open(compressedOut,
PGPLiteralData.BINARY, "pgp", new Date(), new byte[DEFAULT_BUFFER_SIZE])) {
// read input file and write to target file using a buffer
byte[] buf = new byte[DEFAULT_BUFFER_SIZE];
int bytesRead = 0;
while ((bytesRead = contentStream.read(buf)) != -1) {
literalOut.write(buf, 0, bytesRead);
signatureGenerator.update(buf, 0, bytesRead);
literalOut.flush();
}
}
// sign the message.
signatureGenerator.generate().encode(compressedOut);
}
} catch (IOException e) {
throw new EncryptionException(getLogMsg("Exception while signing and
encrypting message with keys ids {0}, {1}", signingKeyID, encryptionKeyID), e);
} catch (org.bouncycastle.openpgp.PGPException e) {
throw new EncryptionException(getLogMsg("Exception while signing and
encrypting message with keys ids {0}, {1}", signingKeyID, encryptionKeyID), e);
} catch (NoSuchProviderException e) {
throw new EncryptionException(getLogMsg("Invalid Provider Exception while
signing and encrypting message with keys ids {0}, {1}", signingKeyID,
encryptionKeyID), e);
} catch (InvalidCipherKeyException e) {
throw new EncryptionException(getLogMsg("Valid keys missing exception
while signing and encrypting message with keys ids {0}, {1}", signingKeyID,
encryptionKeyID), e);
}
return baos.toByteArray(); // cipher text.
}
private PGPSecretKey readSecretKey(InputStream in) throws IOException,
NoSuchProviderException, org.bouncycastle.openpgp.PGPException,
InvalidCipherKeyException {
PGPSecretKey sKey = null;
PGPSecretKeyRingCollection pgpPriv = new PGPSecretKeyRingCollection(in, new
JcaKeyFingerprintCalculator());
// loop through the collection till we find a suitable key.
Iterator it = pgpPriv.getKeyRings();
PGPSecretKeyRing pbr = null;
while (sKey == null && it.hasNext()) {
Object readData = it.next();
if (readData instanceof PGPSecretKeyRing) {
pbr = (PGPSecretKeyRing) readData;
sKey = pbr.getSecretKey();
}
}
if (sKey == null) {
throw new InvalidCipherKeyException("No secret key found in specified key
ring collection.");
}
return sKey;
}