带有公钥/私钥的java-jwt

问题描述 投票:0回答:5

Auth0提供了两个 JWT 库,一个用于 Node:node-jsonwebtoken,一个用于 Java:java-jwt

我创建了私钥/公钥对,并在 Node 中通过 node-jsonwebtoken 成功使用了它:

var key = fs.readFileSync('private.key'); var pem = fs.readFileSync('public.pem'); var header = {...}; var payload = {...}; header.algorithm = "RS256"; var message = jsonwebtoken.sign(payload, key, header); var decoded = jsonwebtoken.verify(message, pem, {algorithm: "RS256"});

但是我发现没有办法在 Java 中使用

java-jwt 做同样的事情。

有人有如何在 Java 中使用 JWT 私钥/公钥的工作示例吗?

java jwt auth0
5个回答
34
投票
我在 Java 中使用了以下 JWT 代码。尝试一下。

import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.PrivateKey; import java.security.PublicKey; import java.util.Date; import java.util.HashMap; import java.util.Map; import io.jsonwebtoken.Claims; import io.jsonwebtoken.Jwts; import io.jsonwebtoken.SignatureAlgorithm; public class JWTJavaWithPublicPrivateKey { public static void main(String[] args) { System.out.println("generating keys"); Map<String, Object> rsaKeys = null; try { rsaKeys = getRSAKeys(); } catch (Exception e) { e.printStackTrace(); } PublicKey publicKey = (PublicKey) rsaKeys.get("public"); PrivateKey privateKey = (PrivateKey) rsaKeys.get("private"); System.out.println("generated keys"); String token = generateToken(privateKey); System.out.println("Generated Token:\n" + token); verifyToken(token, publicKey); } public static String generateToken(PrivateKey privateKey) { String token = null; try { Map<String, Object> claims = new HashMap<String, Object>(); // put your information into claim claims.put("id", "xxx"); claims.put("role", "user"); claims.put("created", new Date()); token = Jwts.builder().setClaims(claims).signWith(SignatureAlgorithm.RS512, privateKey).compact(); } catch (Exception e) { e.printStackTrace(); } return token; } // verify and get claims using public key private static Claims verifyToken(String token, PublicKey publicKey) { Claims claims; try { claims = Jwts.parser().setSigningKey(publicKey).parseClaimsJws(token).getBody(); System.out.println(claims.get("id")); System.out.println(claims.get("role")); } catch (Exception e) { claims = null; } return claims; } // Get RSA keys. Uses key size of 2048. private static Map<String, Object> getRSAKeys() throws Exception { KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA"); keyPairGenerator.initialize(2048); KeyPair keyPair = keyPairGenerator.generateKeyPair(); PrivateKey privateKey = keyPair.getPrivate(); PublicKey publicKey = keyPair.getPublic(); Map<String, Object> keys = new HashMap<String, Object>(); keys.put("private", privateKey); keys.put("public", publicKey); return keys; } }

Maven 依赖



<dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt</artifactId> <version>0.6.0</version> </dependency>
    

15
投票
auth0 java-jwt 库的最新版本(自

3.0.0 起)支持 RSA 和 ECDSA,用于使用公钥/私钥对签署 JWT 令牌。

使用 java-jwt 签署 JWT 的示例(基于

文档)。

import com.auth0.jwt.JWT; import com.auth0.jwt.JWTVerifier; import com.auth0.jwt.algorithms.Algorithm; import com.auth0.jwt.exceptions.JWTCreationException; import com.auth0.jwt.exceptions.JWTVerificationException; import com.auth0.jwt.interfaces.DecodedJWT; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; import java.util.Map; class JwtPKSigningExample { public static void main(String[] args) throws Exception { Map<String, Object> keys = generateRSAKeys(); String token = null; try { RSAPrivateKey privateKey = (RSAPrivateKey) keys.get("private"); Algorithm algorithm = Algorithm.RSA256(null, privateKey); token = JWT.create() .withIssuer("pk-signing-example") .sign(algorithm); } catch (JWTCreationException x) { throw x; } try { RSAPublicKey publicKey = (RSAPublicKey) keys.get("public"); Algorithm algorithm = Algorithm.RSA256(publicKey, null); JWTVerifier verifier = JWT.require(algorithm) .withIssuer("pk-signing-example") .build(); DecodedJWT jwt = verifier.verify(token); System.out.println(jwt.getToken()); } catch (JWTVerificationException x) { throw x; } } private static Map<String, Object> generateRSAKeys() throws Exception { KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA"); keyPairGenerator.initialize(2048); KeyPair keyPair = keyPairGenerator.generateKeyPair(); return Map.of("private", keyPair.getPrivate(), "public", keyPair.getPublic()); } }
    

2
投票
该特定库不支持它。但你可以检查其他人是否有 Java 的情况。请参阅此处:

https://jwt.io/


1
投票
package com.java; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.security.KeyStore; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; import java.security.UnrecoverableKeyException; import java.security.cert.CertificateException; import java.util.Enumeration; import org.jose4j.json.internal.json_simple.parser.ParseException; import org.jose4j.jwk.JsonWebKeySet; import org.jose4j.jws.AlgorithmIdentifiers; import org.jose4j.jws.JsonWebSignature; import org.jose4j.jwt.JwtClaims; import org.jose4j.jwt.MalformedClaimException; import org.jose4j.jwt.consumer.InvalidJwtException; import org.jose4j.jwt.consumer.JwtConsumer; import org.jose4j.jwt.consumer.JwtConsumerBuilder; import org.jose4j.keys.resolvers.JwksVerificationKeyResolver; import org.jose4j.keys.resolvers.VerificationKeyResolver; import org.jose4j.lang.JoseException; public class JWTSigningAndVerification { public static void main(String args[]) throws Exception { String jwt = generateJWT(); validateJWTwithJWKS(jwt); } private static String generateJWT() throws FileNotFoundException, KeyStoreException, IOException, NoSuchAlgorithmException, CertificateException, UnrecoverableKeyException, JoseException { JwtClaims jwt_claims = new JwtClaims(); jwt_claims.setSubject("sub"); jwt_claims.setIssuer("https://domain"); jwt_claims.setIssuedAtToNow(); jwt_claims.setExpirationTimeMinutesInTheFuture(1000000); jwt_claims.setGeneratedJwtId(); jwt_claims.setClaim("sid", "sessionid"); jwt_claims.setClaim("email", "[email protected]"); jwt_claims.setClaim("given_name", "first"); jwt_claims.setClaim("family_name", "last"); JsonWebSignature jws = new JsonWebSignature(); jws.setPayload(jwt_claims.toJson()); String KeyPassword = "p12-key-password"; File file = new File("path-to-key.p12"); InputStream stream = new FileInputStream(file); KeyStore store = KeyStore.getInstance(KeyStore.getDefaultType()); store.load(stream, KeyPassword.toCharArray()); Enumeration e = store.aliases(); String alias = (String) e.nextElement(); PrivateKey key = (PrivateKey) store.getKey(alias, KeyPassword.toCharArray()); jws.setKey(key); jws.setKeyIdHeaderValue("1"); jws.setAlgorithmHeaderValue(AlgorithmIdentifiers.RSA_PSS_USING_SHA512); jws.setHeader("typ", "JWT"); String jwt = jws.getCompactSerialization(); System.out.println(jwt); return jwt; } private static void validateJWTwithJWKS(String jwt) throws JoseException, FileNotFoundException, IOException, ParseException, InvalidJwtException, MalformedClaimException { JsonWebKeySet jsonWebKeySet = new JsonWebKeySet("json-jwks-escaped"); VerificationKeyResolver verificationKeyResolver = new JwksVerificationKeyResolver(jsonWebKeySet.getJsonWebKeys()); JwtConsumer jwtConsumer = new JwtConsumerBuilder().setVerificationKeyResolver(verificationKeyResolver).build(); JwtClaims claims = jwtConsumer.processToClaims(jwt); System.out.println("sub:- " + claims.getSubject()); } }
    

0
投票
如果您有公钥和私钥 pem 文件。

openssl genrsa -aes128 -passout pass:REPLACE_THIS -out privkey.pem 4096 openssl rsa -in privkey.pem -passin pass:REPLACE_THIS -pubout -out public_key.pem
在 Java 代码中,在 pom.xml 中包含以下依赖项:

<dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcprov-jdk18on</artifactId> <version>1.78</version> </dependency>
感谢链接中的回答

Github要点

创建这个类:

package com.zzz.xxx.util; import org.bouncycastle.util.io.pem.PemObject; import org.bouncycastle.util.io.pem.PemReader; import java.io.File; import java.io.FileReader; import java.io.IOException; import java.security.KeyFactory; import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; import java.security.PublicKey; import java.security.spec.InvalidKeySpecException; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; public class PublicPrivateKey { // using bouncycastle to generate public key public static PublicKey getPublicKey() throws InvalidKeySpecException, NoSuchAlgorithmException, IOException { KeyFactory factory = KeyFactory.getInstance("RSA"); File file = new File("E:\\PATH\\public_key.pem"); try (FileReader keyReader = new FileReader(file); PemReader pemReader = new PemReader(keyReader)) { PemObject pemObject = pemReader.readPemObject(); byte[] content = pemObject.getContent(); X509EncodedKeySpec pubKeySpec = new X509EncodedKeySpec(content); PublicKey publicKey = factory.generatePublic(pubKeySpec); return publicKey; } } public static PrivateKey getPrivateKey() throws InvalidKeySpecException, NoSuchAlgorithmException, IOException { KeyFactory factory = KeyFactory.getInstance("RSA"); File file = new File("E:\\PATH\\private_key.pem"); try (FileReader keyReader = new FileReader(file); PemReader pemReader = new PemReader(keyReader)) { PemObject pemObject = pemReader.readPemObject(); byte[] content = pemObject.getContent(); PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(content); PrivateKey privateKey = factory.generatePrivate(privateKeySpec); return privateKey; } } }
然后在需要的地方使用它(示例如下):

return Jwts.builder() .setSubject(subject) .setIssuedAt(new Date()) .setExpiration(expiryDate) //.signWith(SignatureAlgorithm.HS512, appProperties.getAuth().getTokenSecret()) .signWith(privateKey, SignatureAlgorithm.RS512) .compact();
    
© www.soinside.com 2019 - 2024. All rights reserved.