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;
  }

Reply via email to