public static AS2SignedDataGenerator createSigningGenerator(
            AS2SignatureAlgorithm signingAlgorithm, Certificate[] certificateChain, PrivateKey privateKey)
            throws HttpException {
        ObjectHelper.notNull(certificateChain, "certificateChain");
        if (certificateChain.length == 0 || !(certificateChain[0] instanceof X509Certificate)) {
            throw new IllegalArgumentException("Invalid certificate chain");
        }
        ObjectHelper.notNull(privateKey, "privateKey");

        AS2SignedDataGenerator gen = new AS2SignedDataGenerator();

        // Get first certificate in chain for signing
        X509Certificate signingCert = (X509Certificate) certificateChain[0];

        // Create capabilities vector
        SMIMECapabilityVector capabilities = new SMIMECapabilityVector();
        capabilities.addCapability(SMIMECapability.dES_EDE3_CBC);
        capabilities.addCapability(SMIMECapability.rC2_CBC, 128);
        capabilities.addCapability(SMIMECapability.dES_CBC);

        // Create signing attributes
        ASN1EncodableVector attributes = new ASN1EncodableVector();
        attributes.add(new SMIMEEncryptionKeyPreferenceAttribute(
                new IssuerAndSerialNumber(
                        new X500Name(signingCert.getIssuerDN().getName()), signingCert.getSerialNumber())));
        attributes.add(new SMIMECapabilitiesAttribute(capabilities));

        SignerInfoGenerator signerInfoGenerator = null;
        try {
            signerInfoGenerator = new JcaSimpleSignerInfoGeneratorBuilder().setProvider("BC")
                    .setSignedAttributeGenerator(new AttributeTable(attributes))
                    .build(signingAlgorithm.getSignatureAlgorithmName(), privateKey, signingCert);

        } catch (Exception e) {
            throw new HttpException("Failed to create signer info", e);
        }
        gen.addSignerInfoGenerator(signerInfoGenerator);

        // Create and populate certificate store.
        try {
            JcaCertStore certs = new JcaCertStore(Arrays.asList(certificateChain));
            gen.addCertificates(certs);
        } catch (CertificateEncodingException | CMSException e) {
            throw new HttpException("Failed to add certificate chain to signature", e);
        }

        return gen;

    }
@Test
    public void createSigningGeneratorTest() throws Exception {
        AS2SignedDataGenerator gen = SigningUtils.createSigningGenerator(AS2SignatureAlgorithm.SHA1WITHRSA,
                new Certificate[] { signingCert }, signingKP.getPrivate());
        CMSProcessableByteArray sData = new CMSProcessableByteArray(MESSAGE.getBytes(StandardCharsets.UTF_8));
        CMSSignedData signedData = gen.generate(sData, true);

        assertTrue(signedData.verifySignatures((SignerId sid) -> {
            return new JcaSimpleSignerInfoVerifierBuilder().setProvider("BC").build(signingCert);
        }), "Message was wrongly signed");
    }