You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 07:40:29