【问题标题】:Generate and read base64 private key to sign the JWT token from java生成并读取 base64 私钥以从 java 签署 JWT 令牌
【发布时间】:2019-10-18 02:50:00
【问题描述】:

1- 从命令行生成私钥:

openssl genrsa -aes256 -out private.key 2048

  1. 来自java,阅读:

    String privateKey = IOUtils.toString(TestJwtSecurityUtil.class.getResourceAsStream("/private.key"));
    privateKey = privateKey.replace("-----BEGIN RSA PRIVATE KEY-----", "");
    privateKey = privateKey.replace("-----END RSA PRIVATE KEY-----", "");
    privateKey = privateKey.replaceAll("\\s+","");
    
    byte[] encodedKey = DatatypeConverter.parseBase64Binary( privateKey );
    
    
    PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(encodedKey);
    
    KeyFactory kf = KeyFactory.getInstance("RSA");
    PrivateKey pKey = kf.generatePrivate(keySpec); // fails
    

遇到异常:

线程“主”java.security.spec.InvalidKeySpecException 中的异常: java.security.InvalidKeyException:IOException: DerInputStream.getLength():lengthTag=58,太大了。

我尝试转换为base64:

byte[] encodedKey = DatatypeConverter.parseBase64Binary( encodedString );
 PrivateKey pKey = kf.generatePrivate(keySpec); // fails

得到:

Exception in thread "main" java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: invalid key format
    at java.base/sun.security.rsa.RSAKeyFactory.engineGeneratePrivate(RSAKeyFactory.java:251)

问:如何通过这个?为了让私钥被读取,最后我可以唱 JWT 令牌:

final JwtBuilder builder = Jwts.builder().setId("id1")
                ....
                .signWith(signatureAlgorithm, pKey);

【问题讨论】:

标签: java jwt private-key


【解决方案1】:

是的,它是重复的。但是因为我花了超过 1 小时在 SO 网站上寻找它。基于此replybouncycastle 的PEMParser。谢谢,@dave_thompson_085

  1. 创建私钥-公钥:

    • openssl genrsa -out private.key 4096
    • openssl rsa -pubout -in private.key -out public.key
  2. 然后来自java

--

         final PrivateKey pKey = getPrivateKey();

         final SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.RS256; // private key to sign / public to confrim a sign
     final JwtBuilder builder = Jwts.builder().setId("id1")
                    .setIssuedAt(now)
                    .setSubject(subject)
                    .setIssuer(issuer)
                    .setAudience("api")
                    .addClaims(Map.of(
                            "user_name", "test user",
                            "authorities", List.of("ROLE_USER"),
                            "scope", List.of("read", "write"),
                            "client_id", "test-client"
                            )
                    )                     .signWith(signatureAlgorithm, pKey);

String jwt = builder.compact();

地点:

private static PrivateKey getPrivateKey() throws Exception {

        val path = TestUtils.class.getResource("/").getPath();

        final PEMParser pemParser = new PEMParser(new FileReader(path + "/private.key"));
        final JcaPEMKeyConverter converter = new JcaPEMKeyConverter().setProvider("BC");
        final PEMKeyPair object = (PEMKeyPair) pemParser.readObject();
        final KeyPair kp = converter.getKeyPair(object);
        final PrivateKey pKey = kp.getPrivate();

        return pKey;
    }

然后检查,粘贴:生成jwthttps://jwt.io/(或任何其他工具)以查看/检查内容。

放一个 public.key 内容在那里检查签名。看到一切都是绿色的。

【讨论】:

    猜你喜欢
    • 2019-08-27
    • 2022-11-18
    • 2020-02-03
    • 1970-01-01
    • 1970-01-01
    • 2017-07-04
    • 1970-01-01
    • 1970-01-01
    • 2019-11-17
    相关资源
    最近更新 更多