如何验证签名&解密;加密&签名内容

时间:2014-10-30 13:37:00

标签: java encryption cryptography bouncycastle

我有一个充满弹性的城堡代码,可以对消息进行加密和签名(如下所示);现在我需要找到对面的代码;验证签名&解密消息。我寻找过去2天的解决方案一直是徒劳的,因为我只能找到验证签名(或)解密的例子;但不是两个。请在下面找到加密&签名代码;非常感谢任何提示或指示验证签名&解密消息

注意:调用encryptAndSign()方法来加密和签署内容/数据

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<Certificate> certlist = new ArrayList<Certificate>();

        //Add the certificates in Certificate chain to the Certificate list
        for (int i = 0, length = certchain == null ? 0 : certchain.length; i < 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 && !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();         
    }

    }

1 个答案:

答案 0 :(得分:0)

等待2年的答案。我希望你找到解决方案。 为了帮助他人,这里有一个用于阅读SMIME电子邮件和解密附件的示例。它基于发件人使用您的公钥进行加密,并且您获得了密钥和密码来解密邮件。

Security.addProvider(new BouncyCastleProvider());

                    // IMAP encrypt 
                    final KeyStore ks = KeyStore.getInstance("PKCS12");
                    final String password = CERTIFICAT_SMIME_PWD;
                    ks.load(this.class.getClassLoader()
                            .getResourceAsStream(CERTIFICAT_SMIME_PFX), password.toCharArray());
                    final String alias = ks.aliases().nextElement();

                    final PrivateKey pKey = (PrivateKey) ks.getKey(alias, password.toCharArray());

                    final SMIMEEnveloped m = new SMIMEEnveloped((MimeMessage) message);
                    final RecipientInformationStore recipients = m.getRecipientInfos();

                    final X509Certificate cert = (X509Certificate) ks.getCertificate(alias);
                    final RecipientId recId = new JceKeyTransRecipientId(cert);
                    final RecipientInformation recipient = recipients.get(recId);
                    final byte[] content = recipient.getContent(new JceKeyTransEnvelopedRecipient(pKey)
                            .setProvider(BouncyCastleProvider.PROVIDER_NAME));

                    final String providerName = BouncyCastleProvider.PROVIDER_NAME;
                    final MimeBodyPart res = SMIMEUtil.toMimeBodyPart(content);

                    final MimeMultipart parts = (MimeMultipart) res.getContent();

                    for (int i = 0; i < parts.getCount(); i++) {
                        final BodyPart part = parts.getBodyPart(i);
                        if (part.getContent() instanceof Multipart) {
                            multipart = (Multipart) part.getContent();
                        }
                    }