无法从 CMSSigned 数据中获取 SignerCertificate
Unable to get SignerCertificate from CMSSigned data
尝试从 CMS 签名数据中提取 SignerCertificate (X509) 时,我的代码出现错误,未找到证书。为此,我正在使用 bouncycastle 库。
我想我无法签名properly.The附上代码片段,请看一下并纠正我哪里错了。
这是我的签名代码
byte[] tokenBytes = TokenUtils.encode( token );
CMSProcessableByteArray cmsBytes = new CMSProcessableByteArray( tokenBytes );
CMSSignedDataGenerator gen = new CMSSignedDataGenerator();
List certList = new ArrayList();
certList.add(certificate);
Security.addProvider(new BouncyCastleProvider());
ContentSigner sha1Signer = new JcaContentSignerBuilder("SHA1withRSA").setProvider("BC").build(privateKey);
gen.addSignerInfoGenerator(
new JcaSignerInfoGeneratorBuilder(
new JcaDigestCalculatorProviderBuilder().setProvider("BC").build())
.build(sha1Signer, certificate));
signedData = gen.generate(cmsBytes, true);
这是我验证签名的方式
public boolean verifySignature( X509Certificate certificate ) throws TokenException {
Iterator i = signedData.getSignerInfos().getSigners().iterator();
while ( i.hasNext() ) {
SignerInformation s = (SignerInformation) i.next();
try {
if ( s.verify(new JcaSimpleSignerInfoVerifierBuilder().setProvider("BC").build(certificate)))
return true;
} catch ( Exception e ) {
logger.error( "Error verifying signature.", e );
throw new TokenException( "Error verifying token signature.", e );
}
}
return false;
}
以及获取签名者证书的方法
public X509Certificate getSignerCertificate() throws TokenException {
if ( signedData == null )
throw new TokenException( "No one has signed this token yet!" );
try {
//CertStore certStore = signedData.getCertificatesAndCRLs( "Collection", "SUN" );
CertStore certStore = signedData.getCertificatesAndCRLs( "Collection", "SUN" );
SignerInformationStore sis = signedData.getSignerInfos();
Collection c = sis.getSigners();
if ( c.size() != 1 )
throw new TokenException( "Expected one signature, found " + c.size() );
Iterator i = c.iterator();
SignerInformation s = (SignerInformation) i.next();
Collection certs = certStore.getCertificates( s.getSID() );
if ( certs.size() != 1 )
throw new TokenException( "Expected one certificate, found " + certs.size() );
return (X509Certificate) certs.iterator().next();
} catch ( CMSException cmse ) {
throw new TokenException( "Error extracting CertStore from token.", cmse );
} catch ( GeneralSecurityException gse ) {
throw new TokenException( "Provider error extracting certs.", gse );
}
}
您没有将证书添加到签名数据结构中,这可能就是您获得 signerInformation
但未使用 Collection certs = certStore.getCertificates( s.getSID() );
获得证书的原因。要解决此问题,请使用 addCertificates()
method:
将证书添加到您的 CMSSignedData
gen.addSignerInfoGenerator(
new JcaSignerInfoGeneratorBuilder(
new JcaDigestCalculatorProviderBuilder().setProvider("BC").build())
.build(sha1Signer, certificate));
// use this to add the certificates to your signature
gen.addCertificates(certs);
signedData = gen.generate(cmsBytes, true);
希望这对您有所帮助,
尝试从 CMS 签名数据中提取 SignerCertificate (X509) 时,我的代码出现错误,未找到证书。为此,我正在使用 bouncycastle 库。
我想我无法签名properly.The附上代码片段,请看一下并纠正我哪里错了。
这是我的签名代码
byte[] tokenBytes = TokenUtils.encode( token );
CMSProcessableByteArray cmsBytes = new CMSProcessableByteArray( tokenBytes );
CMSSignedDataGenerator gen = new CMSSignedDataGenerator();
List certList = new ArrayList();
certList.add(certificate);
Security.addProvider(new BouncyCastleProvider());
ContentSigner sha1Signer = new JcaContentSignerBuilder("SHA1withRSA").setProvider("BC").build(privateKey);
gen.addSignerInfoGenerator(
new JcaSignerInfoGeneratorBuilder(
new JcaDigestCalculatorProviderBuilder().setProvider("BC").build())
.build(sha1Signer, certificate));
signedData = gen.generate(cmsBytes, true);
这是我验证签名的方式
public boolean verifySignature( X509Certificate certificate ) throws TokenException {
Iterator i = signedData.getSignerInfos().getSigners().iterator();
while ( i.hasNext() ) {
SignerInformation s = (SignerInformation) i.next();
try {
if ( s.verify(new JcaSimpleSignerInfoVerifierBuilder().setProvider("BC").build(certificate)))
return true;
} catch ( Exception e ) {
logger.error( "Error verifying signature.", e );
throw new TokenException( "Error verifying token signature.", e );
}
}
return false;
}
以及获取签名者证书的方法
public X509Certificate getSignerCertificate() throws TokenException {
if ( signedData == null )
throw new TokenException( "No one has signed this token yet!" );
try {
//CertStore certStore = signedData.getCertificatesAndCRLs( "Collection", "SUN" );
CertStore certStore = signedData.getCertificatesAndCRLs( "Collection", "SUN" );
SignerInformationStore sis = signedData.getSignerInfos();
Collection c = sis.getSigners();
if ( c.size() != 1 )
throw new TokenException( "Expected one signature, found " + c.size() );
Iterator i = c.iterator();
SignerInformation s = (SignerInformation) i.next();
Collection certs = certStore.getCertificates( s.getSID() );
if ( certs.size() != 1 )
throw new TokenException( "Expected one certificate, found " + certs.size() );
return (X509Certificate) certs.iterator().next();
} catch ( CMSException cmse ) {
throw new TokenException( "Error extracting CertStore from token.", cmse );
} catch ( GeneralSecurityException gse ) {
throw new TokenException( "Provider error extracting certs.", gse );
}
}
您没有将证书添加到签名数据结构中,这可能就是您获得 signerInformation
但未使用 Collection certs = certStore.getCertificates( s.getSID() );
获得证书的原因。要解决此问题,请使用 addCertificates()
method:
CMSSignedData
gen.addSignerInfoGenerator(
new JcaSignerInfoGeneratorBuilder(
new JcaDigestCalculatorProviderBuilder().setProvider("BC").build())
.build(sha1Signer, certificate));
// use this to add the certificates to your signature
gen.addCertificates(certs);
signedData = gen.generate(cmsBytes, true);
希望这对您有所帮助,