Сгенерируйте и прочитайте закрытый ключ base64, чтобы подписать токен JWT из Java - PullRequest
0 голосов
/ 02 июня 2019

1- Генерация закрытого ключа из командной строки:

openssl genrsa -aes256 -out private.key 2048

из 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

Получено исключение:

Исключение в потоке "main" 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)

Q: как это пройти?Чтобы сделать закрытый ключ читаемым, я мог спеть токен JWT:

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

1 Ответ

0 голосов
/ 02 июня 2019

Да, это дубликат.Но так как я потратил более 1 часа на его поиск на SO сайте.На основании этого ответа и bouncycastle 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;
    }

Затем для проверки вставьте: сгенерировано jwt в https://jwt.io/ (или любой другой инструмент), чтобы просмотреть / проверить содержимое.

поместите туда контент public.key для проверки подписи.Чтобы увидеть, что все зеленое.

...