繁体   English   中英

如何从 Java 中的 PEM 编码公钥生成 JWK?

[英]How to generate a JWK from a PEM encoded public key in Java?

我有一个 PEM 编码的公钥,想在 Java 中从中生成一个 JWK 密钥。 这是我尝试过的:

-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwGhr2bd1u5JVSWEQjo+UWfH1pE0iK9lm
C//yb5my5PnQ2O62etGX3odWvb10J95pWvhahQcC8wPnjvedZtBxcgHiFOprbYYgZWcXarpw9EO6
H/brPiK1h4akjgNxTdBsFHikzaZ1Erd3T4FEzop8j4pRNrjA/tUHEqxdqOl7H0xHJmbv9odn4Mmq
E/azyohY8LhZ/+YUNbEAT3RCb1Z64tUHow4K+K3QFbNTcEQdN69wNvuAskYsSPCR2f8c6hYShhdf
s8NxnGAKgb9APWvkbLw8+n2/sbHyCmWw5ofW1LokXiCxczqK87UCPMaqFwOt2rlBNrzoMMzWAmH7
s9O6qQIDAQAB
-----END PUBLIC KEY-----
-----BEGIN CERTIFICATE-----
MIICuTCCAaGgAwIBAgIJALza9IWWJsHkMA0GCSqGSIb3DQEBCwUAMBwxGjAYBgNVBAMMEVN0ZXBo
YW4gV2lzc2VsL09VMB4XDTIxMDEyMDE5MDAxM1oXDTIxMDMwNjEzMDAxM1owHDEaMBgGA1UEAwwR
U3RlcGhhbiBXaXNzZWwvT1UwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDAaGvZt3W7
klVJYRCOj5RZ8fWkTSIr2WYL//JvmbLk+dDY7rZ60Zfeh1a9vXQn3mla+FqFBwLzA+eO951m0HFy
AeIU6mtthiBlZxdqunD0Q7of9us+IrWHhqSOA3FN0GwUeKTNpnUSt3dPgUTOinyPilE2uMD+1QcS
rF2o6XsfTEcmZu/2h2fgyaoT9rPKiFjwuFn/5hQ1sQBPdEJvVnri1QejDgr4rdAVs1NwRB03r3A2
+4CyRixI8JHZ/xzqFhKGF1+zw3GcYAqBv0A9a+RsvDz6fb+xsfIKZbDmh9bUuiReILFzOorztQI8
xqoXA63auUE2vOgwzNYCYfuz07qpAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAIHX2SudJ6vtpenZ
IhR44/t4WTSfN53lCB2AxOrMFDoa1zZDfM/w7ewtfAND3Y0VGNerpxCh3D2M9NDImgTVKr42ip/+
Dxkfubrph24lW7o3gR2ujlLoY4K9Xvt8xD5jo1PRQC6G9YgS6nOeJjpu55QH1BVT1s2i09WAzNID
l4rIsyRoP9r4FZu2W21UYEzs39uOM81r/zEM+7o2UZXVmx6CLdnPZG4HLvPcqNO2waMBNxGXpwAU
jiND/72QMzzENl/Su5Sc//4TOuNYKdTjMZ5GhCBftpMRL6FebFa9lkhES07e5aVzW4UyC94KpHXH
h+a3MDv2zYm070cF44zDTFQ=
-----END CERTIFICATE-----

Java 方法使用com.nimbusds.jose.jwkvert.xJsonObject

  String getJWTKey(final String rawKey) throws Exception {
    final KeyFactory kf = KeyFactory.getInstance("RSA");
    final SubjectPublicKeyInfo pubKeyInfo =
        (SubjectPublicKeyInfo) new PEMParser(new StringReader(rawKey)).readObject();
    final X509EncodedKeySpec keySpecX509 = new X509EncodedKeySpec(pubKeyInfo.getEncoded());
    final RSAPublicKey rsaPubKey = (RSAPublicKey) kf.generatePublic(keySpecX509);

    // How to get these two?
    List<Base64> certChain = null;
    Base64URL thumbprint = null;

    final RSAKey key = new RSAKey.Builder(rsaPubKey)
        .keyUse(KeyUse.SIGNATURE)
        .algorithm(new Algorithm("RS256"))
        .keyID("mykey")
        .x509CertChain(certChain)
        .x509CertSHA256Thumbprint(thumbprint)
        .build();
 
    return key.toJSONString();

结果是:

{
  "keys": [
    {
      "kty": "RSA",
      "e": "AQAB",
      "use": "sig",
      "alg" : "RS256",
      "kid": "mykey",
      "n": "wGhr2bd1u5JVSWEQjo-UWfH1pE0iK9lmC__yb5my5PnQ2O62etGX3odWvb10J95pWvhahQcC8wPnjvedZtBxcgHiFOprbYYgZWcXarpw9EO6H_brPiK1h4akjgNxTdBsFHikzaZ1Erd3T4FEzop8j4pRNrjA_tUHEqxdqOl7H0xHJmbv9odn4MmqE_azyohY8LhZ_-YUNbEAT3RCb1Z64tUHow4K-K3QFbNTcEQdN69wNvuAskYsSPCR2f8c6hYShhdfs8NxnGAKgb9APWvkbLw8-n2_sbHyCmWw5ofW1LokXiCxczqK87UCPMaqFwOt2rlBNrzoMMzWAmH7s9O6qQ"
    }
  ]
}

查看我缺少的文档

  • x5c
  • x5吨

我的代码中缺少什么? 非常欢迎使用bouncycastle的解决方案。 如果需要,我可以访问证书文件(自行生成)

一路上我了解到除了公钥之外我还需要证书。 所以2方法解决方案(直到我学得更好)是:

/**
   * Returns the JSON formatted JWK based on provided public key / cert
   *
   * @param rawKey - public key as read from disk in pem format
   * @param cert - certificate as read from disk in pem format
   * @return JWK Key as Optional<String>
   */
  public static Optional<String> getJwkString(final String rawKey, final String cert) {
    try {
      final KeyFactory kf = KeyFactory.getInstance("RSA");
      final CertificateFactory cf = CertificateFactory.getInstance("X.509");
      final SubjectPublicKeyInfo pubKeyInfo =
          (SubjectPublicKeyInfo) new PEMParser(new StringReader(rawKey)).readObject();
      final X509EncodedKeySpec keySpecX509 = new X509EncodedKeySpec(pubKeyInfo.getEncoded());
      final RSAPublicKey rsaPubKey = (RSAPublicKey) kf.generatePublic(keySpecX509);

      final X509Certificate rsaCert =
          (X509Certificate) cf.generateCertificate(new ByteArrayInputStream(cert.getBytes()));
      final byte[] certEncoded = rsaCert.getEncoded();
      final List<Base64> certChain = new ArrayList<>();
      certChain.add(Base64.encode(certEncoded));

      final Base64URL thumbprint = Base64URL.from(SamlResourceUtils.getThumbprint(certEncoded));

      final RSAKey key = new RSAKey.Builder(rsaPubKey)
          .keyUse(KeyUse.SIGNATURE)
          .algorithm(new Algorithm("RS256"))
          .x509CertChain(certChain)
          .x509CertThumbprint(thumbprint)
          .keyID("mykey")
          .build();

      return Optional.of(key.toJSONString());

    } catch (final Exception e) {
      SamlResourceUtils.logger.error(e);
    }

    return Optional.empty();
  }

  public static String getThumbprint(final byte[] bytes)
      throws NoSuchAlgorithmException {
    final MessageDigest md = MessageDigest.getInstance("SHA-1");
    md.update(bytes);
    return Hex.toHexString(md.digest());
  }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM