How to include x5t and x5c in JWK output?
Asked Answered
A

1

1

I am trying to call some APIs published by the IRS. They require me to create a JWK and send them the public key.

I was able to generate an RSA JWK key using this code:

package com.propfinancing.jwk;

import com.nimbusds.jose.jwk.KeyUse;
import com.nimbusds.jose.jwk.RSAKey;
import com.nimbusds.jose.jwk.gen.RSAKeyGenerator;
import java.util.UUID;

public class GenerateKey {
  public static void main(String[] args) 
  throws Exception {
    RSAKey jwk = new RSAKeyGenerator(2048)
        .keyUse(KeyUse.SIGNATURE)
        .keyID(UUID.randomUUID().toString())
        .generate();  
    
    System.out.println(jwk);

    System.out.println(jwk.toPublicJWK());
  }
}

Here is a sample output:

{"p":"0nDimdByKTsWOOHWHHkOpdNgIgG5vVmd_Bdc1wQG5lCz1Gh_Iu4z0KaBeAlsoqkak3B2Hv--62nBBIdsqWLOZ4iwed_uIkUItZQNADltG_gEfNAVpY0ESN43ZDykBVOw28FVEiN8ewxZ5rmqKidOgEgMEMbHJ45gqfHm9XD2GLM","kty":"RSA","q":"-TFekmWY2i1_U9K3bDBzJL-cFZfB5JX1qMUiSQhoB_TNymY73UlwZsMap732Jb4v5ZDxIZIjBcHAhRwsEZEEkWyF6mxnUifdbAK4OxaKlw7q1EvUUUzMGqegek-d4ZLwxBD54UgdvTbWxUDlgLlXispfJdr0RwEtOKQzZ53vFU8","d":"DvhjUHjNTZfEeFBAajfZvkznePJmYvXn6cPaclNp3OmMuqYgDSWSciVrP5fyieRX6TgYbaClzoP_UUsXqaTdd1WVySyZEEDh4JGja6n0Y7KwD2DAgEgLhSHwznCp-YV4vtfrLOBpFAwem8S2FaC8vujFzvskiJ3yWfidp-qZGJfGo2wdh2Ry8vkgBRJdEjyVvhKYVR2_UeS3otXQwaLgHHy-Cl8ukiWtXNT5Z5I7CvQOSEy3QpzVUWEnPod6g6j0sfhLMfAkj1i7RfDaJB-8SzlwR5DEhvRrgWJxJw3LWkOcHBAlfepDV63eilM5msDkhlcu_gmzmX-WksyvClgSiw","e":"AQAB","use":"sig","kid":"1ca36b31-c202-4242-8e36-80bb06d2219a","qi":"VvLjYgSBL35kShVGEC2j8BiSAUsyI0QL7aZDdYY6gA-Ba2zSsQQJHg6OISr6rHHJKHopCs1i2PPRd38c7apO8gLwjbk8KsyhYRl864BKfdHfcQo4r3XOH2tDZmsNuc3fpVARKACcQgwtrhGMcIr0M9keghv9wuui7ZQnFPuu0Zk","dp":"n9kZdwbLwJ_eOGTrE4Os6a8OxaYT5U2OYK-KWNT5PLcucfjSIcFYYHQpwfk-qKvUwQva3Z8b8YvKDtujYWLpL-G3U0wSgbt4axzDZ1k3lNgm6HvTBYaBK6yH3L7nRBiXLcXEDdwgsQLnwwdix1RGH9EaQSAMpPJUYKKb8fHVLVs","dq":"MtdCv0WhMOpVbwmvyI_9_gJl2vXyZiu-SiemPhZL-0uT7PZ8wkIof57QwmZ8YOjzpreyqrHBGXyVRdMgnpjiwLTOgayKS_W8NDw90DhiID235YZvFANCJTIMCMhTouEy5B2-jZsEDkWw_d-ms2OdG8D8NqH8crwnuMWvgzVywPs","n":"zNhhwMZJ1f3rNlE62Nyj_lL_ANJYNlIzImH8Uk5QkSO2Wy2oP8yqfcLfvlHyQTP4R5-p7ibT_hC4lEr9BPjseX7Dghd6NMCkRtlhsk2qg7SfSQecNczWZgH5cisMtE_DFWONVpgQRfoaIZV3PSoPAClNTXk52Ni9NaK1mVXsBRP0RD_Hx0r8G8De5UQ8BRNcqYF9hhWzEv1RFLJqZTHMAKeSTmiGJ5Dyur0Wv4kxY73iZtM5ld6f21Q-w9bJ0ar1DVFkmsNtt4Ed20zkj7NOKhBnGqI2VbxQ6WQ7T4Ik6ATf6ujBxLDepme153eH63-1IutZ-Waj8Qfjn2Pt4hVOPQ"}
{"kty":"RSA","e":"AQAB","use":"sig","kid":"1ca36b31-c202-4242-8e36-80bb06d2219a","n":"zNhhwMZJ1f3rNlE62Nyj_lL_ANJYNlIzImH8Uk5QkSO2Wy2oP8yqfcLfvlHyQTP4R5-p7ibT_hC4lEr9BPjseX7Dghd6NMCkRtlhsk2qg7SfSQecNczWZgH5cisMtE_DFWONVpgQRfoaIZV3PSoPAClNTXk52Ni9NaK1mVXsBRP0RD_Hx0r8G8De5UQ8BRNcqYF9hhWzEv1RFLJqZTHMAKeSTmiGJ5Dyur0Wv4kxY73iZtM5ld6f21Q-w9bJ0ar1DVFkmsNtt4Ed20zkj7NOKhBnGqI2VbxQ6WQ7T4Ik6ATf6ujBxLDepme153eH63-1IutZ-Waj8Qfjn2Pt4hVOPQ"}

Everything looks good on the output, but the IRS requires the JWK to include x5t and x5c parameters in the output.

How do I add those?

Thanks, Neil

Aberdare answered 22/11, 2022 at 18:9 Comment(1)
It looks like I need to generate a self-signed certificate. Can I generate one with nimbus-jose-jwt?Aberdare
A
1

I was able to figure out how to generate the self-signed certificate using nimbus-jose-jwt.

Here is my sample code:

package jwk;

import com.nimbusds.jose.jwk.JWKSet;
import com.nimbusds.jose.jwk.KeyUse;
import com.nimbusds.jose.jwk.RSAKey;
import com.nimbusds.jose.jwk.gen.RSAKeyGenerator;
import com.nimbusds.jose.util.Base64;
import com.nimbusds.oauth2.sdk.id.Issuer;
import com.nimbusds.oauth2.sdk.util.X509CertificateUtils;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.PrintWriter;
import java.security.KeyStore;
import java.security.cert.X509Certificate;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.UUID;

public class JWKTest {
  public static void main(String[] args)
  throws Exception {
    // Create a JWK with a random ID
    RSAKey rsaJWK = new RSAKeyGenerator(2048)
        .keyID(UUID.randomUUID().toString())
        .keyUse(KeyUse.SIGNATURE)
        .generate();

    // Create the cert start and expiration dates
    Calendar now = new GregorianCalendar();
    now.add(Calendar.DAY_OF_YEAR, -1);
    Date certStartDate = now.getTime();
    now.add(Calendar.DAY_OF_YEAR, 1);
    now.add(Calendar.YEAR, 10);
    Date certExpirationDate = now.getTime();

    // Generate a self signed certificate
    X509Certificate cert = X509CertificateUtils.generateSelfSigned(
        new Issuer("My issuer"),
        certStartDate,
        certExpirationDate,
        rsaJWK.toRSAPublicKey(),
        rsaJWK.toRSAPrivateKey());

    // Create a key store to hold the certificate
    KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
    keyStore.load(null);
    keyStore.setCertificateEntry("My Cert", cert);
    FileOutputStream outStream = new FileOutputStream(new File("C://Tmp//key.store"));
    keyStore.store(outStream, null);
    outStream.close();

    // Create private key from the certificate
    RSAKey privateJWK = new RSAKey.Builder(rsaJWK)
        .x509CertChain(Collections.singletonList(Base64.encode(cert.getEncoded())))
        .x509CertThumbprint(rsaJWK.computeThumbprint())
        .build();
    PrintWriter writer = new PrintWriter(new FileWriter("C://Tmp//private.jwk"));
    writer.println(privateJWK);
    writer.close();
    
    // Create a public key
    JWKSet publicJWK = new JWKSet(rsaJWK);
    writer = new PrintWriter(new FileWriter("C://Tmp//public.jwk"));
    writer.println(publicJWK);
    writer.close();
  }
}
Aberdare answered 23/12, 2022 at 22:30 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.