Generate, validate and decode PKCS7 file

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view

Generate, validate and decode PKCS7 file

Nicolas Rossi
Hi I wrote because I need to do something basic in theory but very difficult in practice. In general terms I have to sign a file and generate a PKCS7 file from java. This file must have the signature and the content (not detached). Then I will be able to decode the original content and validate it.

First problem: generate file. I was looking for some examples of how to generate files that contain both signature and content data, but I only found sources to generate signature files (without content). Here is an example:

    String text = "texto a encriptar";
    KeyStore keystore = KeystoreUtils.getKeystore("c:/keystore.p12","*****");
    KeyPair     keypair  = KeystoreUtils.getKeys(keystore, "alias", "*****");
    Certificate cert  = keystore.getCertificate("alias");
        CMSSignedDataGenerator generator = new CMSSignedDataGenerator();
        generator.addSigner(keypair.getPrivate(), (X509Certificate) cert, CMSSignedDataGenerator.DIGEST_SHA1);
        ArrayList certList = new ArrayList();
        CertStore certs = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList), "BC");
    CMSSignedData signedData = generator.generate(new CMSProcessableByteArray(text.getBytes()), "BC");

        FileOutputStream output = new FileOutputStream("c:/pkcs7document.p7b");

Second problem: decode and validate the file. I should be able to validate and obtain the original content
from a given pkcs7 file (with the public key because it was signed with the private key).
As I wasn't able to create the mentioned file, I'm using a pkcs7 file generated by other application (not java) to test decoding. This file contains both the signature and the content.
I'm reading it in the following way:

    CMSSignedData s = new CMSSignedData(sigbytes);

    // If I put this line, I can see the original text
    // System.out.println(new String((byte[])s.getSignedContent().getContent()));

    CertStore certs = s.getCertificatesAndCRLs("Collection", "BC");
        SignerInformationStore signers = s.getSignerInfos();
        Collection c = signers.getSigners();
        Iterator it = c.iterator();
        int verified = 0;

        while (it.hasNext())
            X509Certificate cert = null;
            SignerInformation signer = (SignerInformation);
            Collection certCollection = certs.getCertificates(signer.getSID());
            Iterator certIt = certCollection.iterator();
            Cert = (X509Certificate);
            if(signer.verify(cert.getPublicKey(), "BC")) verified++;

As is marked in the code if I uncomment this line

// System.out.println(new String((byte[])s.getSignedContent().getContent()));

I can get the plain text.

But then I have problems with the signature validation process. There are two cases:
a) I 'm only trying to verify the detached signature generated by the java code that I 've mentioned above. When I do that I get this Exception:

Couldn't verify included-content CMS signature
java.lang.IllegalArgumentException: no content specified for signature verification.
java.lang.IllegalArgumentException: no content specified for signature verification.
    at org.bouncycastle.cms.SignerInformation.doVerify(
    at org.bouncycastle.cms.SignerInformation.verify(

b)  I try to verify the signature (with content attached) and I get this Exception:

Couldn't verify included-content CMS signature
org.bouncycastle.cms.CMSException: invalid signature format in message: + no content type id found in signed attributes
    at org.bouncycastle.cms.SignerInformation.doVerify(
    at org.bouncycastle.cms.SignerInformation.verify(

I need help to generate a PKCS7 file with signature and content, and to validate and decode this generated file. I'll appreciate your help very much.