You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@camel.apache.org by "Goyal, Arpit" <ar...@sap.com> on 2017/03/05 23:11:42 UTC

FW: Using PGPDataFormat instead of Bouncy Castle code

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