【问题标题】:How to sign JWT with PKCS#8 PrivateKeyInfo如何使用 PKCS#8 PrivateKeyInfo 对 JWT 进行签名
【发布时间】:2023-01-08 10:13:40
【问题描述】:

我不知道如何使用 PKCS#8 密钥对 JWT 进行签名。关键是类似于这个:

-----BEGIN PRIVATE KEY-----
MIGTAgEAMBNGByqGSM49AgEGCCqGSM49AwEHBHkwdwIBAQQgtbN7M/7webqa1i3k
3UiwERpWUIoRj6nebM7yRyFphVWgCgYIKoHihj0DAQehRANCAAQl6Z+2bWXLgxJC
J2It6UNYSuxios4A1A6/7/7hNs0y3Yus53q6RD1snvMU5yTBewrRALyDz/8MNADm
eN7dRD41
-----END PRIVATE KEY-----

这个 SO 答案中解释了关键:https://stackoverflow.com/a/54981397/1051180

我需要使用 com.nimbusds 库。我认为它应该是可行的,但找不到方法。我找到的最接近的是这个 SO 答案:https://stackoverflow.com/a/57437626/1051180

我设法使用 io.jsonwebtoken 库对其进行签名:

String token = Jwts.builder().signWith(getPrivateKey(), SignatureAlgorithm.ES256).compact();

private static PrivateKey getPrivateKey() {
    PrivateKey key = null;
    try (var pemParser = new PEMParser(privateKeyReader)) {
        var keyInfo = (PrivateKeyInfo) pemParser.readObject();
        key = new JcaPEMKeyConverter().getPrivateKey(keyInfo);      
    }
    return key;
}

背景:我在 .p8 文件中获得了密钥。我用它来签署 JWT,该 JWT 用于在 Sign In with Apple 期间针对 Apple 服务器进行身份验证。

【问题讨论】:

    标签: java jwt apple-sign-in nimbus-jose-jwt p8


    【解决方案1】:

    这是使用从 PEM 资源加载的 ES256 密钥对令牌进行签名的代码(当然,您可以使用另一个密钥源。)

    // --- Signing a token ---
    
    // load PEM as String from "key2.p8" resource
    String p8key;
    ClassLoader cl = Thread.currentThread().getContextClassLoader();
    try (InputStream is = cl.getResourceAsStream("key2.p8");
         InputStreamReader isr = new InputStreamReader(is, StandardCharsets.UTF_8);
         BufferedReader r = new BufferedReader(isr)) {
       p8key = r.lines().collect(Collectors.joining("
    "));
    }
    
    // Load ECKey from the PEM
    ECKey ecJWK = (ECKey) ECKey.parseFromPEMEncodedObjects(p8key);
    
    // Create the EC signer
    JWSSigner signer = new ECDSASigner(ecJWK);
    
    // Create the JWS object with a payload
    JWSObject jwsObject = new JWSObject(
            new JWSHeader.Builder(JWSAlgorithm.ES256).keyID(ecJWK.getKeyID()).build(),
            new Payload("Elliptic cure"));
    
    // Compute the EC signature
    jwsObject.sign(signer);
    
    // Serialize the JWS to compact form
    String jwtToken = jwsObject.serialize();
    
    // print the generated token
    System.out.println(jwtToken);
    
    
    // --- Token signature verification ---
    
    // The recipient creates a verifier with the public EC key
    ECKey ecPublicJWK = ecJWK.toPublicJWK();
    JWSVerifier verifier = new ECDSAVerifier(ecPublicJWK);
    
    // Verify the EC signature
    assertTrue(jwsObject.verify(verifier), "ES256 signature verified");
    assertEquals("Elliptic cure", jwsObject.getPayload().toString());
    

    我只是将 JSON Web Signature (JWS) with Elliptic Curve (EC) example 与您指向的 Does nimbus-jose support construct of ECKey given only a private key? 组合在一起。

    如果您想生成自己的 ES256 私钥,请使用以下命令:

    openssl ecparam -name prime256v1 -genkey -noout -out key.p8
    

    See this article 用于其他密钥类型。

    【讨论】:

      猜你喜欢
      • 2018-05-04
      • 2015-07-02
      • 1970-01-01
      • 1970-01-01
      • 2016-08-01
      • 2018-03-27
      • 1970-01-01
      • 2022-07-16
      • 1970-01-01
      相关资源
      最近更新 更多