Java 用BC验证分离签名
如何使用Java中的BouncyCastle提供程序验证分离的签名(CMS/pkcs#7签名) 当前,下面的我的代码抛出一个异常,消息Java 用BC验证分离签名,java,digital-signature,bouncycastle,Java,Digital Signature,Bouncycastle,如何使用Java中的BouncyCastle提供程序验证分离的签名(CMS/pkcs#7签名) 当前,下面的我的代码抛出一个异常,消息消息摘要属性值与计算值不匹配 Security.addProvider(new BouncyCastleProvider()); File f = new File(filename); byte[] buffer = new byte[(int)f.length()]; DataInputStream in = new DataInputStream(new
消息摘要属性值与计算值不匹配
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");
验证分离的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" );
}
}
}
您可以通过以下代码验证分离的签名:
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;
}
你可以找到这篇文章的答案。发生这种情况的原因是,当S/MIME头不存在时,bouncy castle/open ssl如何处理S/MIME消息。解决方案是在签名之前将S/MIME头添加到消息中。您是否测试了此处找到的代码:?目前,您似乎没有特别考虑分离的数据。我解决了这个问题,您可以找到答案[here][1][1]:您可以通过以下代码验证分离的签名:cmssignedata cms=new cmssignedata(new CMSProcessableByteArray(data_Bytes),Sig_Bytes);cmssignedata类从何而来?@cgajardo org.bounchycastle.cms.cmssignedata