在 Java 中通过 Bouncy Castle 验证 pkcs7 SignedData
Validate pkcs7 SignedData by Bouncy Castle in Java
我正在 Java 中实现 C# SignedCms 功能。
我有一个 pkcs7 SignedData(见我的附件:https://www.dropbox.com/s/yivani7dvh98wpa/SignedData.bin?dl=0),它可以在 C# 中验证:
//signed data is loaded from my attached file.
bool VerifyPKCS7(byte[] signedData)
{
try
{
SignedCms signedCms = new SignedCms();
signedCms.Decode(signedData);
signedCms.CheckSignature(true);
return true;
}
catch
{
}
return false;
}
但无法使用 Java 中的 Bouncy Castle libs(bcprov-jdk15on-153.jar, bcpkix-jdk15on-153.jar) 进行验证:
//encapSigData is loaded from my attached file.
CMSSignedDataParser sp = new CMSSignedDataParser(new JcaDigestCalculatorProviderBuilder().setProvider("BC").build(), encapSigData);
sp.getSignedContent().drain();
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 cert = (X509CertificateHolder)certIt.next();
System.out.println("verify returns: " + signer.verify(new JcaSimpleSignerInfoVerifierBuilder().setProvider("BC").build(cert)));
}
我在第一个代码行(CMSSignedDataParser
构造函数)出现异常:
java.lang.ClassCastException: org.bouncycastle.asn1.DERSequenceParser cannot be cast to org.bouncycastle.asn1.ASN1OctetStringParser
at org.bouncycastle.cms.CMSSignedDataParser.<init>(Unknown Source)
at org.bouncycastle.cms.CMSSignedDataParser.<init>(Unknown Source)
at org.bouncycastle.cms.CMSSignedDataParser.<init>(Unknown Source)
经过一番分析,发现SignedData中contentInfo的content是一个顺序。似乎 bouncycastle 不能接受序列作为 content.
如何在 Java 中使用 bouncycastle 验证此 SignedData?
这里的问题是,与常规 CMS 消息不同,这实际上是 PKCS7 消息。对这些的支持现已添加到 Bouncy Castle 中的 bcpkix API。
您可以在 http://www.bouncycastle.org/betas 154b12 或更高版本的最新测试版中找到它。
我正在 Java 中实现 C# SignedCms 功能。
我有一个 pkcs7 SignedData(见我的附件:https://www.dropbox.com/s/yivani7dvh98wpa/SignedData.bin?dl=0),它可以在 C# 中验证:
//signed data is loaded from my attached file.
bool VerifyPKCS7(byte[] signedData)
{
try
{
SignedCms signedCms = new SignedCms();
signedCms.Decode(signedData);
signedCms.CheckSignature(true);
return true;
}
catch
{
}
return false;
}
但无法使用 Java 中的 Bouncy Castle libs(bcprov-jdk15on-153.jar, bcpkix-jdk15on-153.jar) 进行验证:
//encapSigData is loaded from my attached file.
CMSSignedDataParser sp = new CMSSignedDataParser(new JcaDigestCalculatorProviderBuilder().setProvider("BC").build(), encapSigData);
sp.getSignedContent().drain();
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 cert = (X509CertificateHolder)certIt.next();
System.out.println("verify returns: " + signer.verify(new JcaSimpleSignerInfoVerifierBuilder().setProvider("BC").build(cert)));
}
我在第一个代码行(CMSSignedDataParser
构造函数)出现异常:
java.lang.ClassCastException: org.bouncycastle.asn1.DERSequenceParser cannot be cast to org.bouncycastle.asn1.ASN1OctetStringParser
at org.bouncycastle.cms.CMSSignedDataParser.<init>(Unknown Source)
at org.bouncycastle.cms.CMSSignedDataParser.<init>(Unknown Source)
at org.bouncycastle.cms.CMSSignedDataParser.<init>(Unknown Source)
经过一番分析,发现SignedData中contentInfo的content是一个顺序。似乎 bouncycastle 不能接受序列作为 content.
如何在 Java 中使用 bouncycastle 验证此 SignedData?
这里的问题是,与常规 CMS 消息不同,这实际上是 PKCS7 消息。对这些的支持现已添加到 Bouncy Castle 中的 bcpkix API。
您可以在 http://www.bouncycastle.org/betas 154b12 或更高版本的最新测试版中找到它。