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

Android Kotlin用BouncyCastle实现PS256验签遇算法不存在异常求助

问题

在Android平台使用Kotlin结合BouncyCastle实现PS256签名验证时,查阅文档得知BouncyCastle支持SHA256withRSAandMGF1算法,但运行时抛出「无此算法」异常,请求解决。

相关实现代码:

fun verifySignedContent(cert: String, jwtS: String): Boolean {
        val certFactory: CertificateFactory = CertificateFactory.getInstance("X.509")
        val bytes = ByteArrayInputStream(cert.toByteArray())

        Security.addProvider(BouncyCastleProvider())

        val signedJWT = SignedJWT.parse(jwtS)

        val signature = signedJWT.signature

        val sig = Signature.getInstance("SHA256withRSAandMGF1", "BC")
        println("Signature: " + signature.toJSONString())

        sig.initVerify(certFactory.generateCertificate(bytes))
        sig.update(signature.decode())

        val flagSig = sig.verify(signedJWT.signature.decode())
        println("Signature is valid: $flagSig")
        return flagSig
    }

已添加的Gradle依赖:

implementation 'org.bouncycastle:bcprov-jdk18on:1.71'
implementation 'org.bouncycastle:bcpkix-jdk18on:1.71'
解决方案
  • 修正算法名称:PS256对应的标准算法标识在BouncyCastle中是SHA256withRSA/PSS,而非SHA256withRSAandMGF1——后者不是Java兼容的标准算法命名,这是导致「无此算法」异常的核心原因。
  • 提前加载Provider:将Security.addProvider(BouncyCastleProvider())放在所有加密操作之前,确保BouncyCastle被优先作为算法提供者。
  • 修正验证输入数据:签名验证需要对JWT的原始签名输入(header与payload通过.拼接的字节数据)进行哈希,而非直接传入签名值。可通过SignedJWT的signingInput属性直接获取该数据。
  • 明确PSS参数(可选但推荐):手动配置PSSParameterSpec,指定哈希算法、MGF1参数、盐长度(PS256对应32字节),确保与签名生成端的参数完全一致,避免因默认参数差异导致验证失败。

修正后的代码:

fun verifySignedContent(cert: String, jwtS: String): Boolean {
    // 优先加载BouncyCastle Provider
    Security.addProvider(BouncyCastleProvider())

    // 指定BC作为证书工厂的提供者
    val certFactory = CertificateFactory.getInstance("X.509", "BC")
    val certInputStream = ByteArrayInputStream(cert.toByteArray())
    val x509Cert = certFactory.generateCertificate(certInputStream) as X509Certificate

    val signedJWT = SignedJWT.parse(jwtS)

    // 使用正确的PS256对应算法名称
    val sig = Signature.getInstance("SHA256withRSA/PSS", "BC")

    // 配置符合PS256标准的PSS参数
    val pssSpec = PSSParameterSpec(
        "SHA-256",
        "MGF1",
        MGF1ParameterSpec.SHA256,
        32, // PS256要求盐长度等于哈希长度(SHA256为32字节)
        1
    )
    sig.setParameter(pssSpec)

    sig.initVerify(x509Cert.publicKey)
    // 更新JWT的签名输入数据(header + "." + payload)
    sig.update(signedJWT.signingInput)

    // 验证签名值
    val isValid = sig.verify(signedJWT.signature.decode())
    println("Signature is valid: $isValid")
    return isValid
}

内容的提问来源于stack exchange,提问作者Sarthak

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 19:22:38