title: How to verify signature & decrypt a ; Encrypted & Signed content
body: <p>I have a bouncy castle code that encrypts and sign a message(listed below) ; now I need to find the code for opposite end ; Verify the signature &amp; decrypt the message. My search to find a solution for the past 2 days has been futile, as I could only find example for either verifying the signature (or) for decryption ; but not both. Please find below the encryption &amp; signing code ; would greatly appreciate any hint or direction to <strong>Verify the signature &amp; decrypt the message</strong></p>
  
  <p>Note : The method encryptAndSign() is called to encrypt and sign the Content/data</p>
  
  <pre><code>import java.io.FileInputStream;
  import java.io.FileNotFoundException;
  import java.io.IOException;
  import java.io.InputStream;
  import java.security.KeyStore;
  import java.security.KeyStoreException;
  import java.security.NoSuchAlgorithmException;
  import java.security.PrivateKey;
  import java.security.Security;
  import java.security.cert.Certificate;
  import java.security.cert.CertificateException;
  import java.security.cert.X509Certificate;
  import java.util.ArrayList;
  import java.util.Collection;
  import java.util.Iterator;
  import java.util.List;
  
  import javax.naming.NamingException;
  
  import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
  import org.bouncycastle.cert.X509CertificateHolder;
  import org.bouncycastle.cert.jcajce.JcaCertStore;
  import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
  import org.bouncycastle.cms.CMSAlgorithm;
  import org.bouncycastle.cms.CMSEnvelopedData;
  import org.bouncycastle.cms.CMSEnvelopedDataGenerator;
  import org.bouncycastle.cms.CMSException;
  import org.bouncycastle.cms.CMSProcessableByteArray;
  import org.bouncycastle.cms.CMSSignedData;
  import org.bouncycastle.cms.CMSSignedDataGenerator;
  import org.bouncycastle.cms.CMSTypedData;
  import org.bouncycastle.cms.SignerInformation;
  import org.bouncycastle.cms.SignerInformationStore;
  import org.bouncycastle.cms.jcajce.JcaSignerInfoGeneratorBuilder;
  import org.bouncycastle.cms.jcajce.JcaSimpleSignerInfoVerifierBuilder;
  import org.bouncycastle.cms.jcajce.JceCMSContentEncryptorBuilder;
  import org.bouncycastle.cms.jcajce.JceKeyTransRecipientInfoGenerator;
  import org.bouncycastle.jce.provider.BouncyCastleProvider;
  import org.bouncycastle.operator.ContentSigner;
  import org.bouncycastle.operator.DefaultDigestAlgorithmIdentifierFinder;
  import org.bouncycastle.operator.DefaultSignatureAlgorithmIdentifierFinder;
  import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
  import org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder;
  import org.bouncycastle.util.Store;
  import org.bouncycastle.util.encoders.Base64;
  
  public final class EncryptorNsigner {
  
       public byte[] encryptAndSign(final String content, final String selfSignedCert,
              final String encryptionCert) throws CertificateException, IOException,
              KeyStoreException, Exception {
          byte[] signedBytes;
  
          //Get key store
          KeyStore keyStore = this.getKeyStore();
  
          //Setup provider
          CMSSignedDataGenerator signatureGenerator = this.setUpProvider(
                  keyStore, selfSignedCert);
  
          //Encrypt data
          byte[] encryptBytes = this.encryptData(content.getBytes("UTF-8"),
                  getEncyptionCertFromKeystore(keyStore, encryptionCert), null);
  
          //Sign the encrypted data
          signedBytes = this.signPkcs7(encryptBytes, signatureGenerator);
  
          return Base64.encode(signedBytes);
      }
  
  
      private KeyStore getKeyStore() throws NamingException, KeyStoreException, 
                          FileNotFoundException, CertificateException, IOException,
                          NoSuchAlgorithmException{
  
          ...
          return keystore;
      }
  
      private X509Certificate getEncyptionCertFromKeystore(final KeyStore keystore, final String encryptionCertName) 
              throws CertificateException, IOException, KeyStoreException{
  
          Certificate c = keystore.getCertificate(encryptionCertName);
  
          X509CertificateHolder certHolder = new X509CertificateHolder(c.getEncoded());
  
          return new JcaX509CertificateConverter().setProvider( "BC" )
                    .getCertificate(certHolder );
      }
  
      private CMSSignedDataGenerator setUpProvider(final KeyStore keystore, String signCertName) throws Exception {
  
          Security.addProvider(new BouncyCastleProvider());
  
          //Get certificate chain
          Certificate[] certchain = (Certificate[]) keystore.getCertificateChain(signCertName);
  
  
          final List&lt;Certificate&gt; certlist = new ArrayList&lt;Certificate&gt;();
  
          //Add the certificates in Certificate chain to the Certificate list
          for (int i = 0, length = certchain == null ? 0 : certchain.length; i &lt; length; i++) {
              certlist.add(certchain[i]);
          }
  
          //Class for storing certificates for later lookup
          Store certstore = new JcaCertStore(certlist);
  
          //Get certificate
          Certificate cert = keystore.getCertificate(signCertName);
  
          String algorithm = "SHA1withRSA";
          String keyStorePwd = "....";
  
          ContentSigner signer = new JcaContentSignerBuilder(algorithm).setProvider("BC").
                  build((PrivateKey) (keystore.getKey(signCertName, keyStorePwd.toCharArray())));
  
          CMSSignedDataGenerator generator = new CMSSignedDataGenerator();
  
  
          generator.addSignerInfoGenerator(new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().setProvider("BC").
                  build()).build(signer, (X509Certificate) cert));
  
          generator.addCertificates(certstore);
  
          return generator;
      }
  
  
      private byte[] signPkcs7(final byte[] content, final CMSSignedDataGenerator generator) 
              throws CMSException, IOException {
  
          CMSTypedData cmsdata = new CMSProcessableByteArray(content);
          CMSSignedData signeddata = generator.generate(cmsdata, true);
          return signeddata.getEncoded();
      }
  
       private byte[] encryptData(byte[] dataToEncrypt, X509Certificate recipientCert, String algorithmName) throws IOException{
  
          CMSEnvelopedDataGenerator edGen = new CMSEnvelopedDataGenerator();                                    
  
          CMSEnvelopedData ed;
          AlgorithmIdentifier digestAlgorithm;
          if (algorithmName!=null &amp;&amp; !algorithmName.isEmpty()){
               digestAlgorithm = new DefaultDigestAlgorithmIdentifierFinder().find(new DefaultSignatureAlgorithmIdentifierFinder().find(algorithmName));
  
  
              try {
  
                  edGen.addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator(recipientCert).setProvider("BC"));
                  ed = edGen.generate(new CMSProcessableByteArray(dataToEncrypt),
                                                  new JceCMSContentEncryptorBuilder(digestAlgorithm.getAlgorithm())
                                                         .setProvider("BC").build());
              } catch (Exception e) {
                  throw new IOException(e.getMessage());        
              }
  
          }
          else{
              try {
  
                  edGen.addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator(recipientCert).setProvider("BC"));
                  ed = edGen.generate(new CMSProcessableByteArray(dataToEncrypt),
                                                  new JceCMSContentEncryptorBuilder(CMSAlgorithm.DES_EDE3_CBC) //Default algorithmName = DES_EDE3_CBC
                                                         .setProvider("BC").build());
              } catch (Exception e) {
                  throw new IOException(e.getMessage());        
              }
          }    
  
          return ed.getEncoded();         
      }
  
      }
  </code></pre>