8

How can I verify a detached signature (CMS/pkcs #7 signature) using the BouncyCastle provider in Java?

Currently, my code below throws an exception with the message message-digest attribute value does not match calculated value

Security.addProvider(new BouncyCastleProvider());

File f = new File(filename);
byte[] buffer = new byte[(int)f.length()];
DataInputStream in = new DataInputStream(new FileInputStream(f));
in.readFully(buffer);
in.close();

CMSSignedData signature = new CMSSignedData(buffer);
SignerInformation signer = (SignerInformation) signature.getSignerInfos().getSigners().iterator().next();
CertStore cs = signature.getCertificatesAndCRLs("Collection", "BC");
Iterator iter = cs.getCertificates(signer.getSID()).iterator();
X509Certificate certificate = (X509Certificate) iter.next();

CMSProcessable sc = signature.getSignedContent();

signer.verify(certificate, "BC");
Donal Fellows
  • 120,022
  • 18
  • 134
  • 199
meriem
  • 191
  • 1
  • 2
  • 6
  • Have you tested the code found here: http://bouncy-castle.1462172.n4.nabble.com/How-to-verify-detached-PKCS7-signature-with-Stream-content-data-td1464668.html ? Currently, there is no particular spot where you actually seem to take the detached data into account. – Maarten Bodewes Dec 05 '11 at 22:24
  • I solved this issue you can find answer [here][1] [1]: http://stackoverflow.com/questions/8590426/s-mime-verification-with-x509-certificate/20649242#20649242 – Swapnil Dec 18 '13 at 03:43

3 Answers3

10

You can verify detached signature by the following code :

public static boolean verif_Detached(String signed_file_name,String original_file_name) throws IOException, CMSException, NoSuchAlgorithmException, NoSuchProviderException, CertStoreException, CertificateExpiredException, CertificateNotYetValidException{

    boolean result= false;
    Security.addProvider(new BouncyCastleProvider()); 

    File f = new File(signed_file_name);
    byte[] Sig_Bytes = new byte[(int)f.length()];
    DataInputStream in = new DataInputStream(new FileInputStream(f));
    in.readFully(Sig_Bytes);
    in.close();

    File fi = new File(original_file_name);
    byte[] Data_Bytes = new byte[(int)fi.length()];
    DataInputStream input = new DataInputStream(new FileInputStream(fi));
    input.readFully(Data_Bytes);
    input.close();

    try{
        CMSSignedData cms = new CMSSignedData(new CMSProcessableByteArray(Data_Bytes), Sig_Bytes); 
        CertStore certStore = cms.getCertificatesAndCRLs("Collection", "BC"); 
        SignerInformationStore signers = cms.getSignerInfos(); 
        Collection c = signers.getSigners(); 
        Iterator it = c.iterator(); 
        while (it.hasNext()) { 
            SignerInformation signer = (SignerInformation) it.next(); 
            Collection certCollection = certStore.getCertificates(signer.getSID()); 
            Iterator certIt = certCollection.iterator(); 
            X509Certificate cert = (X509Certificate) certIt.next();
            cert_signer=cert;
            result=signer.verify(cert, "BC");
        }
    }catch(Exception e){
        e.printStackTrace();
        result=false;
    }
    return result; 
}
Joe
  • 2,805
  • 6
  • 38
  • 58
meriem
  • 191
  • 1
  • 2
  • 6
1

You can find the answer to this post here. This happening because how bouncy castle/open ssl treats the S/MIME message when S/MIME headers are not present.Solution is to add S/MIME headers to the message before signimg

Community
  • 1
  • 1
Swapnil
  • 2,225
  • 3
  • 22
  • 46
1

the key for verify detached pKCS7 is use of CMSTypedStream ,like code bellow:

public void verifySign(byte[] signedData,byte[]bPlainText) throws Exception {
                InputStream is  = new ByteArrayInputStream(bPlainText);             
                CMSSignedDataParser sp = new CMSSignedDataParser(new CMSTypedStream (is),signedData);
                CMSTypedStream signedContent = sp.getSignedContent();           

                 signedContent.drain();





                  //CMSSignedData s = new CMSSignedData(signedData); 
                  Store certStore = sp.getCertificates(); 

                  SignerInformationStore signers = sp.getSignerInfos(); 
                    Collection c = signers.getSigners();
                    Iterator it = c.iterator();
                    while (it.hasNext()) 
                    { 
                        SignerInformation signer = (SignerInformation)it.next(); 
                        Collection certCollection = certStore.getMatches(signer.getSID()); 

                        Iterator certIt = certCollection.iterator(); 

                        X509CertificateHolder certHolder = (X509CertificateHolder)certIt.next(); 




                        if ( !signer.verify(new 
            JcaSimpleSignerInfoVerifierBuilder().setProvider("BC").build(certHolder))) 
                        { 
                            throw new DENException("Verification FAILED! "); 

                        } 
                        else
                        {
                            logger.debug("verify success" );
                        }


                    } 
    }
hoefer
  • 31
  • 1
  • 4
  • you can verify detached signature by this code : CMSSignedData cms = new CMSSignedData(new CMSProcessableByteArray(Data_Bytes), Sig_Bytes); – meriem Feb 13 '12 at 13:26