Android下使用BouncyCastle验证PKCS#7分离签名遇算法异常
解决PKCS#7签名验证时「算法不存在」的异常
问题拆解
报错里的1.2.840.113549.1.1.11就是SHA-256+RSA签名算法的标准OID标识。出现这个异常,核心原因要么是BouncyCastle(BC)加密库没注册好,要么是代码里的验证逻辑有问题。
具体解决步骤
1. 先确保BC加密库正确注册到系统
Android默认不会自动加载BC Provider,必须手动注册,建议在应用启动时完成(比如全局Application的onCreate方法里):
import java.security.Security import org.bouncycastle.jce.provider.BouncyCastleProvider // 检查是否已注册,避免重复添加 if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null) { Security.addProvider(BouncyCastleProvider()) }
2. 修正签名验证的代码逻辑
你现在直接把SHA-256哈希值传给CMSProcessableByteArray,可能导致BC无法正确识别对应的签名算法。可以做两个关键调整:
- 显式指定签名算法,避免自动匹配出错;
- 遍历签名者时,遇到空证书集合直接跳过,不要触发异常。
修改后的代码:
private fun verifySignature(sha256Hash: ByteArray, base64Signature: String): Boolean { // 先确保BC已注册 if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null) { Security.addProvider(BouncyCastleProvider()) } val signedData = CMSSignedData( CMSProcessableByteArray(sha256Hash), Base64.decode(base64Signature, Base64.DEFAULT).inputStream() ) val store: Store<X509CertificateHolder> = signedData.certificates signedData.signerInfos.signers.forEach { signer -> try { val certCollection = store.getMatches(signer.sid as Selector<X509CertificateHolder>) // 无匹配证书直接跳过当前签名者 if (certCollection.isEmpty()) return@forEach val certHolder = certCollection.first() val cert = JcaX509CertificateConverter().setProvider("BC").getCertificate(certHolder) // 显式指定SHA256withRSA算法,对应报错里的OID val verifier = JcaSimpleSignerInfoVerifierBuilder() .setProvider("BC") .setSignatureAlgorithm("SHA256withRSA") .build(cert) if (signer.verify(verifier)) { return true } } catch (e: Exception) { e.printStackTrace() } } return false }
3. 检查依赖版本(可选)
你当前使用的BC 1.72版本和compileSdk 30兼容,但如果上面的方法无效,可以尝试升级到最新稳定版(比如1.77),Gradle依赖修改为:
implementation 'org.bouncycastle:bcpkix-jdk18on:1.77' implementation 'org.bouncycastle:bcprov-jdk18on:1.77' implementation 'org.bouncycastle:bcutil-jdk18on:1.77'
4. 确认签名数据本身没问题
要保证你传入的base64签名,确实是用SHA-256+RSA算法生成的PKCS#7格式签名,避免因签名算法或格式不匹配导致的异常。
内容的提问来源于stack exchange,提问作者Bill Zangardi
相关产品推荐
相关产品推荐

