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

对接IRS API:如何在JWK输出中添加x5t与x5c参数

为RSA JWK添加x5t和x5c参数(NimbusDS实现)

要满足IRS的要求添加x5t和x5c参数,你需要将RSA密钥与X.509证书关联:

  • x5t:证书的SHA-1指纹(Base64URL编码)
  • x5c:X.509证书链的Base64编码(DER格式,去除PEM头尾)

以下是修改后的代码,包含证书生成与JWK构建的完整流程:

依赖补充(如需生成自签名证书)

如果用BouncyCastle简化证书生成,添加Maven依赖:

<dependency>
    <groupId>org.bouncycastle</groupId>
    <artifactId>bcpkix-jdk15on</artifactId>
    <version>1.70</version>
</dependency>
<dependency>
    <groupId>com.nimbusds</groupId>
    <artifactId>nimbus-jose-jwt</artifactId>
    <version>9.31</version>
</dependency>

完整代码实现

package com.propfinancing.jwk;

import com.nimbusds.jose.jwk.KeyUse;
import com.nimbusds.jose.jwk.RSAKey;
import com.nimbusds.jose.jwk.gen.RSAKeyGenerator;
import com.nimbusds.jose.util.X509CertificateChain;
import org.bouncycastle.asn1.x500.X500Name;
import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.operator.ContentSigner;
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
import org.bouncycastle.asn1.x509.BasicConstraints;
import org.bouncycastle.asn1.x509.Extension;
import org.bouncycastle.cert.jcajce.JcaX509ExtensionUtils;

import java.security.KeyPair;
import java.security.Security;
import java.security.cert.X509Certificate;
import java.util.Date;
import java.util.UUID;
import java.math.BigInteger;
import java.security.SecureRandom;

public class GenerateKey {

    static {
        // 注册BouncyCastle安全提供者
        Security.addProvider(new BouncyCastleProvider());
    }

    // 生成自签名X.509证书(正式环境请使用IRS认可的CA签发证书)
    private static X509Certificate generateSelfSignedCert(KeyPair keyPair) throws Exception {
        X500Name issuer = new X500Name("CN=IRS API Client, OU=Finance, O=PropFinancing, L=New York, ST=NY, C=US");
        X500Name subject = issuer; // 自签名证书,签发者与主体一致
        Date startDate = new Date();
        Date endDate = new Date(startDate.getTime() + 365L * 24 * 60 * 60 * 1000); // 有效期1年

        // 构建签名器
        ContentSigner contentSigner = new JcaContentSignerBuilder("SHA256WithRSAEncryption")
                .setProvider("BC")
                .build(keyPair.getPrivate());

        // 构建证书
        X509v3CertificateBuilder certBuilder = new JcaX509v3CertificateBuilder(
                issuer,
                new BigInteger(64, new SecureRandom()),
                startDate,
                endDate,
                subject,
                keyPair.getPublic()
        );

        // 添加证书扩展
        JcaX509ExtensionUtils extUtils = new JcaX509ExtensionUtils();
        certBuilder.addExtension(Extension.subjectKeyIdentifier, false, extUtils.createSubjectKeyIdentifier(keyPair.getPublic()));
        certBuilder.addExtension(Extension.authorityKeyIdentifier, false, extUtils.createAuthorityKeyIdentifier(keyPair.getPublic()));
        certBuilder.addExtension(Extension.basicConstraints, true, new BasicConstraints(true));

        // 生成并返回证书
        return new JcaX509CertificateConverter().setProvider("BC").getCertificate(certBuilder.build(contentSigner));
    }

    public static void main(String[] args) throws Exception {
        // 生成RSA密钥对
        RSAKey rsaKey = new RSAKeyGenerator(2048)
                .keyUse(KeyUse.SIGNATURE)
                .keyID(UUID.randomUUID().toString())
                .generate();
        KeyPair keyPair = rsaKey.toKeyPair();

        // 生成自签名证书
        X509Certificate cert = generateSelfSignedCert(keyPair);

        // 构建包含x5t和x5c的JWK
        RSAKey jwkWithCert = new RSAKey.Builder(rsaKey)
                // 设置x5c:证书链(单证书时为单元素数组)
                .x509CertChain(new X509CertificateChain(cert))
                // 自动计算并设置x5t:证书SHA-1指纹的Base64URL编码
                .x509CertSHA1Thumbprint(rsaKey.computeX509CertSHA1Thumbprint(cert))
                .build();

        // 输出完整JWK(含私钥、x5t、x5c)
        System.out.println(jwkWithCert);
        // 输出公钥JWK(含x5t、x5c,用于提交给IRS)
        System.out.println(jwkWithCert.toPublicJWK());
    }
}

关键说明

  1. x5c参数:通过x509CertChain方法传入证书链,NimbusDS会自动将证书DER编码为Base64字符串,填充到x5c字段中。
  2. x5t参数:调用computeX509CertSHA1Thumbprint方法自动计算证书的SHA-1指纹并编码为Base64URL格式,无需手动计算。
  3. 正式环境注意:对接IRS时必须使用IRS认可的CA签发的证书,自签名证书仅用于测试。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 11:50:33