用BC验证分离的签名

时间:2011-11-23 14:08:54

标签: java digital-signature bouncycastle

如何使用Java中的BouncyCastle提供程序验证分离的签名(CMS / pkcs#7签名)?

目前,我的代码会抛出一条带有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");

3 个答案:

答案 0 :(得分:8)

您可以通过以下代码验证分离的签名:

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; 
}

答案 1 :(得分:0)

验证分离的密钥pKCS7是使用CMSTypedStream,如下面的代码:

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" );
                        }


                    } 
    }

答案 2 :(得分:0)

您可以找到此帖here的答案。发生这种情况是因为当S / MIME标头不存在时,bouncy castle / open ssl如何处理S / MIME消息。解决方案是在signimg之前向消息添加S / MIME标头