我想验证一些来自微软的JWT的签名.我正在使用Spring-Boot,JJWT库和以下端点:https://login.microsoftonline.com/common/discovery/v2.0/keys
端点返回JSON公钥数组.这是数组中的一个示例.
{
"kty": "RSA",
"use": "sig",
"kid": "9FXDpbfMFT2SvQuXh846YTwEIBw",
"x5t": "9FXDpbfMFT2SvQuXh846YTwEIBw",
"n": "kvt1VmR4nwkNM8jMU0wmj2gSS8NznbOt2pZI6Z7HQT_esF7W19GZR7Y72Xo1i5zXRDM9o3GeTIjBrnr3yy41Q_EaUQ7C-b-Hmg94Vy7EBZyBhi_mznz0dYWs2MIXwR86Nni9TmgTXvjgTPF2YGJoZt4TwcMFefW8rijCVyNrCBA0XspDouNJavvG0BEMXYigoThFjLRXS5U3h4BDfNZFZZS3dyliNOXfgRn2k7oITz8h_ueiPvmDRFh38AeQgx1cELhKWc3P5ugtttraSwgH7nP2NUguO9nCrHuL6TZ-KWpmRWZqwH-jYKFQVt3CDpzwNM6XJL-oHbl1x-gI3YYX5w",
"e": "AQAB",
"x5c": [
"MIIDBTCCAe2gAwIBAgIQZSAeaqWig4BHC1ksmNNcgjANBgkqhkiG9w0BAQsFADAtMSswKQYDVQQDEyJhY2NvdW50cy5hY2Nlc3Njb250cm9sLndpbmRvd3MubmV0MB4XDTE3MDUwNjAwMDAwMFoXDTE5MDUwNzAwMDAwMFowLTErMCkGA1UEAxMiYWNjb3VudHMuYWNjZXNzY29udHJvbC53aW5kb3dzLm5ldDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJL7dVZkeJ8JDTPIzFNMJo9oEkvDc52zrdqWSOmex0E/3rBe1tfRmUe2O9l6NYuc10QzPaNxnkyIwa5698suNUPxGlEOwvm/h5oPeFcuxAWcgYYv5s589HWFrNjCF8EfOjZ4vU5oE1744EzxdmBiaGbeE8HDBXn1vK4owlcjawgQNF7KQ6LjSWr7xtARDF2IoKE4RYy0V0uVN4eAQ3zWRWWUt3cpYjTl34EZ9pO6CE8/If7noj75g0RYd/AHkIMdXBC4SlnNz+boLbba2ksIB+5z9jVILjvZwqx7i+k2filqZkVmasB/o2ChUFbdwg6c8DTOlyS/qB25dcfoCN2GF+cCAwEAAaMhMB8wHQYDVR0OBBYEFGKpXQNrF5IoxS6bL4F92+gxOJlIMA0GCSqGSIb3DQEBCwUAA4IBAQA3HgW5SoHlvvQVxqqi+mtscDZLhNfe13iG/nx8Er5il82b79RVydNs+f9sYxc4T4ctnrZu7x5e7jInJedNdAlrPorBdw+SfvKJsmiNndXugMew1FlcQTQVIFDCbziaJav8rKyMxPfeKkc1aixbajWZkKg6OPmmJn2ceTocbn8PMQy20xNvcWUwgF5FZZIuPqu6feOLJcUIYw+0JFZ265xka30QXpmytcIxajIzpD4PRdCIBuVSqgXacAs4t4+w+OhnosD72yvXck8M4GwX1j+vcuyw0yhDGNMmqsHWP7H3jnJiGDrKhhdVyplzDhTfv2Whbv/dIDn+meLE3yyC5yGL"
],
"issuer": "https://login.microsoftonline.com/{tenantid}/v2.0"
}
Run Code Online (Sandbox Code Playgroud)
在JJWT中我实现了SigningKeyResolver接口,我需要返回一个RSAPublicKey实例来进行验证.我遇到的问题是从JSON正确创建Key.
我是从模数和指数开始的吗?
BigInteger modulus = new BigInteger(1, Base64.decodeBase64(jsonKey.getN()));
BigInteger exponent = new BigInteger(1, Base64.decodeBase64(jsonKey.getE()));
publicKey = KeyFactory.getInstance("RSA").generatePublic(new RSAPublicKeySpec(modulus, exponent));
Run Code Online (Sandbox Code Playgroud)
我是从x5c开始,生成X509Certificate对象并从那里拉出PublicKey吗?
CertificateFactory factory = CertificateFactory.getInstance("X.509");
X509Certificate cert = (X509Certificate) factory
.generateCertificate(new ByteArrayInputStream(
DatatypeConverter.parseBase64Binary(jsonKey.getX5c())));
publicKey = (RSAPublicKey)cert.getPublicKey();
Run Code Online (Sandbox Code Playgroud)
这两种方法都没有结果.
如果我从模数和指数生成RSAPublicKey,我应该能够打印Base64Binary编码的密钥以匹配x5c属性吗?也许这不是我应该如何验证.
我可能会误解如何使用它.
与往常一样,任何文档也受到赞赏.
我已经开始使用JJWT在我的服务器应用程序上处理JWT.
我的JWT秘密将存储在resources文件夹中,我将在Properties课程中加载秘密.
该JJWT提供了三种方法来签署JWT,一个用途byte[],其他用途String和其他用途Key:
JwtBuilder signWith(SignatureAlgorithm var1, byte[] var2);
JwtBuilder signWith(SignatureAlgorithm var1, String var2);
JwtBuilder signWith(SignatureAlgorithm var1, Key var2);
Run Code Online (Sandbox Code Playgroud)
问题:关于安全性,字符集和其他问题,我应该使用哪些建议?
一会儿,我站着String,因为Properties回来了String.
我正在寻求JWT在我的应用程序中实现,我正在通过以下参考进行一些研发:https://stormpath.com/blog/jwt-java-create-verify.generateToken()当我尝试verifyToken()通过提取声明集时,我成功地能够实现该方法.我不明白apiKey.getSecret()从哪里来.你能指导我吗?
以下代码供参考:
public class JJWTDemo {
private static final String secret = "MySecrete";
private static String generateToken(){
String id = UUID.randomUUID().toString().replace("-", "");
Date now = new Date();
Date exp = new Date(System.currentTimeMillis() + (1000*30)); // 30 seconds
String token = Jwts.builder()
.setId(id)
.setIssuedAt(now)
.setNotBefore(now)
.setExpiration(exp)
.signWith(SignatureAlgorithm.HS256, secret)
.compact();
return token;
}
private static void verifyToken(String token){
Claims claims = Jwts.parser().
setSigningKey(DatatypeConverter.parseBase64Binary(apiKey.getSecret()))
.parseClaimsJws(token).getBody();
System.out.println("----------------------------");
System.out.println("ID: " + claims.getId());
System.out.println("Subject: …Run Code Online (Sandbox Code Playgroud) 我不想使用密钥(我没有)验证 JWT,我只想解码 JWT 并读取有效负载。这可以使用 jsonwebtoken.io:jjwt 来实现吗?API 中似乎缺少一个方法。
当然,我可以自己对令牌进行拆分和 Base64 解码,但感觉就像是人们期望从 JWT 库中获得的最基本的功能;因此我怀疑我错过了一些东西。
我正在尝试读取从 Google OpenID Connect 的 Id 令牌生成的 Json Web 令牌(JWT),以获取声明并使用jjwt库进行验证。我已经尝试了几种方法来使用下面的代码修复它。
String publicKeyFromJsonFile = "-----BEGIN PUBLIC KEY-----xxxxxxx-----END PUBLIC KEY-----"
Claims claims = Jwts.parser()
.setSigningKey(publicKeyFromJsonFile)
.parseClaimsJws(jwt).getBody();
System.out.println(claims);
Run Code Online (Sandbox Code Playgroud)
但我收到此错误:
java.lang.IllegalArgumentException: Key bytes can only be specified for HMAC signatures. Please specify a PublicKey or PrivateKey instance
Run Code Online (Sandbox Code Playgroud)
请遵循什么是正确的方法?
我在应用程序中使用JWT进行登录身份验证过程。要生成令牌,我正在使用:
Jwts.builder().setSubject(username).signWith(SignatureAlgorithm.HS512, MacProvider.generateKey()).compact();
Run Code Online (Sandbox Code Playgroud)
生成的令牌:
eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOlaJlaG91c2VAZGV2ZXJldXgub3JnIn0.5SX-aU-p_RlfC3CZa-YXnQu_YR7RsG2Xfim3LOmlqxjzrIyZizQFKZ8H
当我在jwt.io调试器中解码此令牌时,它告诉我无效的签名。我无法找到此失败的原因,因为我可以在要验证的有效负载中看到用户名。有人可以指出我的问题吗?我需要更改代码中的任何内容吗?
Auth0提供了两个JWT库,一个用于Node:node-jsonwebtoken,一个用于Java:java-jwt。它原来是java的智威汤逊不支持公钥/私钥对。
但是,另一个Java库jjwt库声称支持该功能。但是,该文档没有显示如何在jjwt中使用自己的公钥/私钥对。
我创建了私钥/公钥对,并在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"});
Run Code Online (Sandbox Code Playgroud)
我implementation group: 'io.jsonwebtoken', name: 'jjwt-api', version: '0.10.6'用作依赖项。
我想创建一个 JWT 令牌,如下所示:
@Value("${jwt.token.secret}")
private Key secret;
JwtToken.builder().value(Jwts.builder()
.setClaims(createClaims(account))
.setSubject(subject.toString())
.setIssuedAt(Date.from(createdDateTime))
.setExpiration(Date.from(expirationDateTime))
.signWith(secret)
.compact()).expiration(expirationDateTime.toString()).build()
Run Code Online (Sandbox Code Playgroud)
我曾经在 中提供一个字符串application.properties并引用该键,如上所示,但不推荐使用字符串作为密钥。我应该如何创建密钥秘密?
我继承了一个在 POM.xml 中有这个的 java 项目:
<properties>
<jjwt.version>0.11.1</jjwt.version>
</properties>
// from https://github.com/jwtk/jjwt#maven
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
<version>${jjwt.version}</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-impl</artifactId>
<version>${jjwt.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-jackson</artifactId> <!-- or jjwt-gson if Gson is preferred -->
<version>${jjwt.version}</version>
<scope>runtime</scope>
</dependency>
// what is this "jjwt" dep, and why might it be using a different version?
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)
这个“jjwt”dep 是什么,为什么它可能使用不同的版本?
我在https://github.com/jwtk/jjwt 上没有看到任何提及
我的客户向我发送了一个 JWT,我需要使用他们的公钥验证此 JWT。我正在使用 Java 和 JJWT 框架来验证此令牌。我知道使用 HS256 解码此令牌,但使用 RS256 我不知道。
他们的配置是:
在这里编辑以改进我的问题。我正在使用的 jjwt 解析示例:
Claims String secret = "-----BEGIN CERTIFICATE-----myx5ckey-----END CERTIFICATE-----"
byte[] dataBytes = Base64.getEncoder().encode(secret.getBytes());
byte[] byteKey = Base64.getDecoder().decode(dataBytes);
X509EncodedKeySpec X509publicKey = new X509EncodedKeySpec(byteKey);
KeyFactory kf = KeyFactory.getInstance("RSA");
PublicKey publicKey = kf.generatePublic(X509publicKey);
Claims body = null;
body = Jwts.parser().setSigningKey(publicKey.getEncoded())
.parseClaimsJws(idToken)
.getBody();
java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: invalid key format
at sun.security.rsa.RSAKeyFactory.engineGeneratePublic(RSAKeyFactory.java:205)
Run Code Online (Sandbox Code Playgroud)
如何使用我显示的 JWKS 信息验证收到的令牌?(上图)
jjwt ×10
java ×7
jwt ×7
security ×2
cryptography ×1
hmac ×1
oauth-2.0 ×1
openid ×1
spring-boot ×1