Java 如何使用bouncy castle对签名数据进行签名?
在签名者之前,一切正常。由于以下异常,请验证(…):Java 如何使用bouncy castle对签名数据进行签名?,java,encryption,cryptography,digital-signature,bouncycastle,Java,Encryption,Cryptography,Digital Signature,Bouncycastle,在签名者之前,一切正常。由于以下异常,请验证(…): import java.security.Security; import java.security.cert.X509Certificate; import java.util.Collection; import java.util.Iterator; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.cert.jcajce.JcaX5
import java.security.Security;
import java.security.cert.X509Certificate;
import java.util.Collection;
import java.util.Iterator;
import org.bouncycastle.cert.X509CertificateHolder;
import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
import org.bouncycastle.cms.CMSSignedData;
import org.bouncycastle.cms.SignerInformation;
import org.bouncycastle.cms.SignerInformationStore;
import org.bouncycastle.cms.jcajce.JcaSimpleSignerInfoVerifierBuilder;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.util.Store;
import org.bouncycastle.util.encoders.Base64;
public class VerifySignature {
public static void main(String[] args) throws Exception {
File p7s = new File("D:\\SBI-DATA\\file\\signature_2.txt") ;
int size = ((int) p7s.length());
byte[] sig = new byte[size];
File f = new File("D:\\SBI-DATA\\file\\plain.txt") ;
int sizecontent = ((int) f.length());
byte[] Data_Bytes = new byte[sizecontent];
Security.addProvider(new BouncyCastleProvider());
CMSSignedData signedData = new CMSSignedData(new CMSProcessableByteArray(Data_Bytes), sig);
Store store = signedData.getCertificates();
SignerInformationStore signers = signedData.getSignerInfos();
Collection c = signers.getSigners();
Iterator it = c.iterator();
while (it.hasNext()) {
SignerInformation signer = (SignerInformation) it.next();
Collection certCollection = store.getMatches(signer.getSID());
Iterator certIt = certCollection.iterator();
X509CertificateHolder certHolder = (X509CertificateHolder) certIt.next();
X509Certificate certFromSignedData = new JcaX509CertificateConverter().setProvider(BC_PROVIDER).getCertificate(certHolder);
if (signer.verify(new JcaSimpleSignerInfoVerifierBuilder().setProvider(BC_PROVIDER).build(certFromSignedData))) {
System.out.println("Signature verified");
} else {
System.out.println("Signature verification failed");
}
}
}
}
我真的不知道我做错了什么。有人能告诉我发生了什么事吗?我想你签了两次,一次直接使用
签名,另一次使用ContentSigner
。您只需要对数据进行签名,而不需要对签名进行签名
因此,解决方案应该是将signature.sign()
替换为text.getBytes()
,或者text.getBytes(StandardCharsets.UTF_8)
如果您想显式定义text
的字符集,而不是使用某些系统默认值。您可以避免使用,“BC
来显式定义提供程序。Bouncy Castle CMS与Oracle提供程序的效果一样好,您可能希望在将来插入另一个提供程序。尤其是当您有一个包含Base64编解码器的库时!嘿,我也面临同样的问题。。。你解决这个问题了吗???@user3921002I我想要数据签名。任何人都知道如何从签名中分离公钥。你说得对!只要去掉那个讨厌的签名对象,写下“CMSTypedData msg=newcmsprocessablebytearray(theRawBytesofMyFile);”而且它有效!在BC 1.49:D:D:D上测试
import java.security.Security;
import java.security.cert.X509Certificate;
import java.util.Collection;
import java.util.Iterator;
import org.bouncycastle.cert.X509CertificateHolder;
import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
import org.bouncycastle.cms.CMSSignedData;
import org.bouncycastle.cms.SignerInformation;
import org.bouncycastle.cms.SignerInformationStore;
import org.bouncycastle.cms.jcajce.JcaSimpleSignerInfoVerifierBuilder;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.util.Store;
import org.bouncycastle.util.encoders.Base64;
public class VerifySignature {
public static void main(String[] args) throws Exception {
File p7s = new File("D:\\SBI-DATA\\file\\signature_2.txt") ;
int size = ((int) p7s.length());
byte[] sig = new byte[size];
File f = new File("D:\\SBI-DATA\\file\\plain.txt") ;
int sizecontent = ((int) f.length());
byte[] Data_Bytes = new byte[sizecontent];
Security.addProvider(new BouncyCastleProvider());
CMSSignedData signedData = new CMSSignedData(new CMSProcessableByteArray(Data_Bytes), sig);
Store store = signedData.getCertificates();
SignerInformationStore signers = signedData.getSignerInfos();
Collection c = signers.getSigners();
Iterator it = c.iterator();
while (it.hasNext()) {
SignerInformation signer = (SignerInformation) it.next();
Collection certCollection = store.getMatches(signer.getSID());
Iterator certIt = certCollection.iterator();
X509CertificateHolder certHolder = (X509CertificateHolder) certIt.next();
X509Certificate certFromSignedData = new JcaX509CertificateConverter().setProvider(BC_PROVIDER).getCertificate(certHolder);
if (signer.verify(new JcaSimpleSignerInfoVerifierBuilder().setProvider(BC_PROVIDER).build(certFromSignedData))) {
System.out.println("Signature verified");
} else {
System.out.println("Signature verification failed");
}
}
}
}
Exception in thread "main" org.bouncycastle.cms.CMSSignerDigestMismatchException: message-digest attribute value does not match calculated value
at org.bouncycastle.cms.SignerInformation.doVerify(Unknown Source)
at org.bouncycastle.cms.SignerInformation.verify(Unknown Source)
at my.package.VerifySignature.main(VerifySignature.java:64)