"e": "AQAB"
JWKS - Json Web 密钥集是什么意思
{
"keys": [
{
"kty": "RSA", #key type
"e": "AQAB", #Question - what does "e" mean or stand for. And what values can e take. What is AQAB here.
"use": "sig", #verify client assertion signature. This means what is the use of the key. Answer - to verify signature. Right?
"kid": "somebase64encodestring", #key id
"alg": "RS256", #key algoritham. Here it is RSA.
"n": "anotherbase64encodestring" #This is the actual public key base64 encoded.
} …
Run Code Online (Sandbox Code Playgroud) 我收到两个JWT:一个OpenID Connect令牌(id_token)和一个访问令牌(access_token).OpenID的情况或多或少都很清楚 - 我可以使用JWKs Endpoint验证它:https://smth.com/JWKS .
例如(https://bitbucket.org/b_c/jose4j/wiki/JWT%20Examples):
HttpsJwks httpsJkws = new HttpsJwks("https://smth.com/JWKS");
HttpsJwksVerificationKeyResolver httpsJwksKeyResolver = new HttpsJwksVerificationKeyResolver(httpsJkws);
jwtConsumer = new JwtConsumerBuilder()
.setVerificationKeyResolver(httpsJwksKeyResolver)
.setExpectedAudience(...)
.setExpectedIssuer(...)
.build();
Run Code Online (Sandbox Code Playgroud)
问题是如何继续使用访问令牌.我可以从中提取userId和userDetails,但我想我还需要验证它吗?
如果我尝试与令牌相同,我会收到错误:UnresolvableKeyException: Unable to find a suitable verification key for JWS w/ header {"alg" : "RS256", "kid":"1"}
.事实上,"孩子"没有关键:"1",这个值"1"似乎有点奇怪?
我做错了吗?
我想生产JWT并用HMAC_SHA256签名.对于那个任务,我必须使用jose4j.我试图基于秘密生成密钥:
SecretKeySpec key = new SecretKeySpec(("secret").getBytes("UTF-8"), AlgorithmIdentifiers.HMAC_SHA512);
Run Code Online (Sandbox Code Playgroud)
但是它会生成40位密钥,而使用HMAC_SHA256签名需要512位密钥.
我正在使用jose4j来验证和处理JWT.JWT如下所示,它在JWT主页中通过验证.
但是,我不能用jose4j java库做同样的事情.异常抱怨我设置的验证密钥.但是库中定义了许多类型的键,我尝试过但没有运气.代码如下:
import java.util.Map;
import org.jose4j.jwt.JwtClaims;
import org.jose4j.jwt.consumer.InvalidJwtException;
import org.jose4j.jwt.consumer.JwtConsumer;
import org.jose4j.jwt.consumer.JwtConsumerBuilder;
import org.jose4j.keys.HmacKey;
public class YGJWT {
public static void main(String args[]) throws InvalidJwtException {
String jwt = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ";
String secret = "secret";
JwtConsumer jwtConsumer = new JwtConsumerBuilder()
.setVerificationKey(new HmacKey(secret.getBytes())) //what kind of key do i need to use it here?
.build();
JwtClaims jwtClaims = jwtConsumer.processToClaims(jwt);
Map<String, Object> claimsMap = jwtClaims.getClaimsMap();
claimsMap.forEach((String key, Object val) -> {
System.out.println(key + ": " + val.toString());
});
}
}
Run Code Online (Sandbox Code Playgroud)
任何帮助表示赞赏.
如何在Java中验证Azure B2C id令牌的JWT签名?我已经使用google open-id connect成功验证了签名,但我还没有成功验证Microsoft Azure B2C jwt id令牌的签名.我在这里使用了示例B2C游乐场应用程序https://aadb2cplayground.azurewebsites.net/.注册并编辑我的个人资料后,我抓住了这个id令牌.
eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik1uQ19WWmNBVGZNNXBPWWlKSE1iYTlnb0VLWSIsImtpZCI6Ik1uQ19WWmNBVGZNNXBPWWlKSE1iYTlnb0VLWSJ9.eyJhdWQiOiJiYjJhMmUzYS1jNWU3LTRmMGEtODhlMC04ZTAxZmQzZmMxZjQiLCJpc3MiOiJodHRwczovL3N0cy53aW5kb3dzLm5ldC83NzU1MjdmZi05YTM3LTQzMDctOGIzZC1jYzMxMWY1OGQ5MjUvIiwiaWF0IjoxNDU4NDMzMDIzLCJuYmYiOjE0NTg0MzMwMjMsImV4cCI6MTQ1ODQzNjkyMywiYW1yIjpbInB3ZCJdLCJpcGFkZHIiOiI3NC4xMzkuMjEzLjE3NSIsIm5hbWUiOiJib2I1Iiwibm9uY2UiOiJMNlNvekpjeVVEc2lYQ2t0NVQwN1NBPT0iLCJvaWQiOiJjNjc0NDA1Yy05ZGIxLTRmN2EtYTIwMy1jNzZkNDk1Zjk5ZDAiLCJwdWlkIjoiMTAwM0JGRkQ5NkQ0NThCMSIsInN1YiI6InozTGRJOWUtSFlWeXpCSl9sOE9RTndWYnRQM3BnbHBwREo3NjJ2TmEycFkiLCJ0aWQiOiI3NzU1MjdmZi05YTM3LTQzMDctOGIzZC1jYzMxMWY1OGQ5MjUiLCJ1bmlxdWVfbmFtZSI6InJib290aF9jYWxsaWJyaXR5LmNvbSNFWFQjQGZhYnJpa2FtYjJjLm9ubWljcm9zb2Z0LmNvbSIsInVwbiI6InJib290aF9jYWxsaWJyaXR5LmNvbSNFWFQjQGZhYnJpa2FtYjJjLm9ubWljcm9zb2Z0LmNvbSIsInZlciI6IjEuMCJ9.MPPkvUc0bHuVyf8hr4JZ0hG0mLE2pT7maDR-10e3XR8m6FtrsmQlkgvhnzfao94jPzDzX_CnG_Asfnqv04JeIpvQXBlViO63AlfZaZVllLByeJti5Uat1WepMPz5MRydk6b2o5w_xRfl7QOI-L9Yt8r7-rQX1FMuIPfvvsUity-M-H8s0XInvihxiKEHU_wvz6U017Tgjs4qcrpILM5Ziaxfb7oSxgECl3EDWAoITDy5B-rYCH_o-7mhxHQauUYgH5dUV2MrM8iuaMPoRc3r9Xk38SyfgS1-4taK_bi_AIutyOBX4O3cWbrvGDshQbHBW4BmjctTBT-xUPWboydpuA
Run Code Online (Sandbox Code Playgroud)
我指出我的java代码使用以下端点进行令牌验证.
https://login.microsoftonline.com/fabrikamb2c.onmicrosoft.com/discovery/v2.0/keys?p=b2c_1_sign_in
在写这篇文章的时候,这就是那个终点的json.
{
"keys": [
{"kid":"IdTokenSigningKeyContainer","use":"sig","kty":"RSA","e":"AQAB","n":"tLDZVZ2Eq_DFwNp24yeSq_Ha0MYbYOJs_WXIgVxQGabu5cZ9561OUtYWdB6xXXZLaZxFG02P5U2rC_CT1r0lPfC_KHYrviJ5Y_Ekif7iFV_1omLAiRksQziwA1i-hND32N5kxwEGNmZViVjWMBZ43wbIdWss4IMhrJy1WNQ07Fqp1Ee6o7QM1hTBve7bbkJkUAfjtC7mwIWqZdWoYIWBTZRXvhMgs_Aeb_pnDekosqDoWQ5aMklk3NvaaBBESqlRAJZUUf5WDFoJh7yRELOFF4lWJxtArTEiQPWVTX6PCs0klVPU6SRQqrtc4kKLCp1AC5EJqPYRGiEJpSz2nUhmAQ"}
]
}
Run Code Online (Sandbox Code Playgroud)
这是我使用的java代码
package com.example
import org.jose4j.jwk.HttpsJwks
import org.jose4j.jwt.JwtClaims
import org.jose4j.jwt.consumer.InvalidJwtException
import org.jose4j.jwt.consumer.JwtConsumer
import org.jose4j.jwt.consumer.JwtConsumerBuilder
import org.jose4j.keys.resolvers.HttpsJwksVerificationKeyResolver
class AzureB2CPOC7 {
public static talk(){
String jwt = "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik1uQ19WWmNBVGZNNXBPWWlKSE1iYTlnb0VLWSIsImtpZCI6Ik1uQ19WWmNBVGZNNXBPWWlKSE1iYTlnb0VLWSJ9.eyJhdWQiOiJiYjJhMmUzYS1jNWU3LTRmMGEtODhlMC04ZTAxZmQzZmMxZjQiLCJpc3MiOiJodHRwczovL3N0cy53aW5kb3dzLm5ldC83NzU1MjdmZi05YTM3LTQzMDctOGIzZC1jYzMxMWY1OGQ5MjUvIiwiaWF0IjoxNDU4NDMzMDIzLCJuYmYiOjE0NTg0MzMwMjMsImV4cCI6MTQ1ODQzNjkyMywiYW1yIjpbInB3ZCJdLCJpcGFkZHIiOiI3NC4xMzkuMjEzLjE3NSIsIm5hbWUiOiJib2I1Iiwibm9uY2UiOiJMNlNvekpjeVVEc2lYQ2t0NVQwN1NBPT0iLCJvaWQiOiJjNjc0NDA1Yy05ZGIxLTRmN2EtYTIwMy1jNzZkNDk1Zjk5ZDAiLCJwdWlkIjoiMTAwM0JGRkQ5NkQ0NThCMSIsInN1YiI6InozTGRJOWUtSFlWeXpCSl9sOE9RTndWYnRQM3BnbHBwREo3NjJ2TmEycFkiLCJ0aWQiOiI3NzU1MjdmZi05YTM3LTQzMDctOGIzZC1jYzMxMWY1OGQ5MjUiLCJ1bmlxdWVfbmFtZSI6InJib290aF9jYWxsaWJyaXR5LmNvbSNFWFQjQGZhYnJpa2FtYjJjLm9ubWljcm9zb2Z0LmNvbSIsInVwbiI6InJib290aF9jYWxsaWJyaXR5LmNvbSNFWFQjQGZhYnJpa2FtYjJjLm9ubWljcm9zb2Z0LmNvbSIsInZlciI6IjEuMCJ9.MPPkvUc0bHuVyf8hr4JZ0hG0mLE2pT7maDR-10e3XR8m6FtrsmQlkgvhnzfao94jPzDzX_CnG_Asfnqv04JeIpvQXBlViO63AlfZaZVllLByeJti5Uat1WepMPz5MRydk6b2o5w_xRfl7QOI-L9Yt8r7-rQX1FMuIPfvvsUity-M-H8s0XInvihxiKEHU_wvz6U017Tgjs4qcrpILM5Ziaxfb7oSxgECl3EDWAoITDy5B-rYCH_o-7mhxHQauUYgH5dUV2MrM8iuaMPoRc3r9Xk38SyfgS1-4taK_bi_AIutyOBX4O3cWbrvGDshQbHBW4BmjctTBT-xUPWboydpuA";
HttpsJwks httpsJkws = new HttpsJwks("https://login.microsoftonline.com/fabrikamb2c.onmicrosoft.com/discovery/v2.0/keys?p=b2c_1_sign_in");
HttpsJwksVerificationKeyResolver httpsJwksKeyResolver = new HttpsJwksVerificationKeyResolver(httpsJkws);
JwtConsumer jwtConsumer = new JwtConsumerBuilder()
.setRequireExpirationTime() // the JWT must have an expiration time
.setAllowedClockSkewInSeconds(3600) // allow some leeway in validating time based claims …
Run Code Online (Sandbox Code Playgroud) 我需要从 JWT 中提取声明。
看来这应该是理所当然的事情。
它已签名,从我得到的标题中:
{
"alg": "RS256",
"typ": "JWT"
}
Run Code Online (Sandbox Code Playgroud)
智威汤逊:
eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX25hbWUiOiJtYXJrLnN0YW5nQGRoaWdyb3VwaW5jLmNvbSIsInNjb3BlIjpbIm9wZW5pZCJdLCJyb2xlcyI6WyJKT0JTRUVLRVIi XSwiam9ic2Vla2VySWQiOiJ3TDFkTWdQckZWOUl5dEZZIiwiZXhwIjoxNDg4Mzk1ODE5LCJhdXRob3JpdGllcyI6WyJKT0JTRUVLRVIiXSwianRpIjoiNWRiYjNkYzQtNGI3NC00MDYyLTgzMmQtYjE1MTgw YWZhZjllIiwiY2xpZW50X2lkIjoiZWZjIn0.NxiF4x39na3KdDUFz2zxqy1zSfJkj4FdKHflpgJUxzMgBq8bbJIFVkmwAUYA6_YXm6kGFcyTMgdiRIJpqc5buDPdV1vkzh4QKFTxMz9MF4i3vtIQ21V m5W12KikWdWGGUXMD4udJwu7rmuIBtNIa-ciZOPADNrrXfuw7iML1xxAA-C0f4OTbiKqiXr3QEUZwcqZB17qfh_dVRRxgO-_uHUg84JDcpXEDQPzPWX68u1EHH4J6IcpMKn1VY9k3RcZU6pq-ndzQgBlKd VM2owA6i-UM9p1zSz7ZX_2wx0czEEcNF1rMdeIv5yxP9YEpWb14-GUG4qgpn_rAIQBJ7eu7xw
它在 jwt.io 网站上解码得很好,但由于我没有“秘密”密钥,所以它显示为“无效签名”。这很好,我不想验证它。
我想要的只是声明,但是当我使用 Java 库对其进行解码时,除了错误之外什么也没有得到。
如果我手动解码它(即 split/base64 解码),那就没问题了。
那么,我对 Java 库做错了什么?
我的 Java 应用程序正在接收 JWT。我有 PEM 格式的公钥:
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAixn0CGu8/M4txn4pdp8K
m8RQfVa+cHX25/a5sPmzP49u7YlQsRvtOexzgdwDcfUJm3hHMZcbZBtrHKsS8q4Q
QtGQioyVml8EaLuFNFYisaIEldVyRbXFG54FNp03vSU9ImS/cOiM9swo+1w5JgWO
F9efy7JO40LA9E7lv64COUYjFhrn+HRZuKoblL19+Sj49FyXexAUS29UM9PfIdY6
ar1FA8cxzPqW7EkXZ0Mua3IzNnYcjMvUL9TJwoLAAz9S1Tv4Is5jupy9UXkuJ4r8
Jx9DqI3Q3ur0VekYSd5tnTI4K+no9ABCFVv7+6Q45Ec2eB0xMwlqI+phcGhGMVCX
1QIDAQAB
-----END PUBLIC KEY-----
Run Code Online (Sandbox Code Playgroud)
我知道我可以使用 aJwtConsumer
来验证和解码 JWT:
JwtConsumer jwtConsumer = new JwtConsumerBuilder()
.setRequireExpirationTime()
.setVerificationKey(publicKey) // what do I pass here?
.build();
Run Code Online (Sandbox Code Playgroud)
但是如何将我的 PEM 文件转换为.setVerificationKey()
.
我正在生成一个公钥/私钥对,我将使用它通过 jose4j 对 JWT 进行数字签名。它在创建和验证令牌方面也工作得很好。但是一旦我重新启动服务器,之前颁发的令牌就会失效。我觉得每次我重新启动服务器时它都会创建新密钥。这就是我在构造函数中生成密钥的方式:
rsaJsonWebKey = RsaJwkGenerator.generateJwk(2048);
// Give the JWK a Key ID (kid), which is just the polite thing to do
rsaJsonWebKey.setKeyId("secretKey");
Run Code Online (Sandbox Code Playgroud)
当我们尝试创建类的新实例时也会发生这种情况。它说令牌无效。
任何帮助,将不胜感激。谢谢..
参考这个,我必须使用算法AGCM256-KW加密.我正在使用Java Cryptography,我没有找到任何这样的算法.我发现最接近的是AES_256/GCM/NoPadding,但它没有KW(密钥包装).
这是我的测试代码
public void testEncryption(String algo) {
String shared_secret = "LyQnklSrxsk3Ch2+AHi9HoDW@//x1LwM123QP/ln";
try {
// Step 1 - Create SHA-256 digest of the shared key
MessageDigest md = MessageDigest.getInstance("SHA-256");
byte[] digest = md.digest(shared_secret.getBytes("UTF-8"));
// Step 2 - generate a 256 bit Content Encryption Key(CEK)
KeyGenerator kg = KeyGenerator.getInstance("AES");
kg.init(256);
SecretKey cek = kg.generateKey();
// Step 3 - encrypt the CEK using 256 bit digest generated in Step 1
// and 96 bit random IV. …
Run Code Online (Sandbox Code Playgroud) 为了验证 JWT,我使用 jose4j 从 url 获取证书,在这种情况下,从谷歌:
HttpsJwks httpsJkws = new HttpsJwks("https://www.googleapis.com/oauth2/v3/certs");
HttpsJwksVerificationKeyResolver httpsJwksKeyResolver = new HttpsJwksVerificationKeyResolver(httpsJkws);
//httpsJkws.setSimpleHttpGet(simpleHttpGet);
JwtConsumer jwtConsumer = new JwtConsumerBuilder()
.setVerificationKeyResolver(httpsJwksKeyResolver)
.build(); // create the JwtConsumer instance
Run Code Online (Sandbox Code Playgroud)
但是,这让我得到一个证书错误:
PKIX 路径构建失败:sun.security.provider.certpath.SunCertPathBuilderException:无法找到请求目标的有效认证路径
好的,是的,我可以使用一些脚本将它添加到 JVM 的信任库中,但我不想(基本上,它不是自签名证书,并且可以通过常规浏览器正常工作)。大多数时候,我使用 Apache HTTP 客户端 4.x,出于某种原因,在那里,调用确实可以正常工作:
try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
HttpResponse httpResponse = httpClient.execute(new HttpGet("https://www.googleapis.com/oauth2/v3/certs"));
String response = (httpResponse.getEntity() != null) ? EntityUtils.toString(httpResponse.getEntity()) : null;
log.debug(response);
} catch (IOException e) {
log.error("I/O Error when retrieving content from '" + jwksEndpointUrl + "': " + e.getMessage()); …
Run Code Online (Sandbox Code Playgroud) 我正在尝试使用node.js中的jsonwebtoken验证jose4j生成的json Web令牌,我看到以下错误:
[错误:PEM_read_bio_PUBKEY失败]
jose4j代码基本上直接取自示例:
RsaJsonWebKey key = RsaJwkGenerator.generateJwk(2048);
key.setKeyId("global.authenticated");
byte[] raw = key.getKey().getEncoded();
Base64.Encoder encoder = Base64.getEncoder();
System.out.printf("Public Key [%s]\n", encoder.encodeToString(raw));
JwtClaims claims = new JwtClaims();
claims.setIssuer("global.gen");
claims.setAudience("global.cons");
claims.setExpirationTimeMinutesInTheFuture(12 * 60);
claims.setGeneratedJwtId();
claims.setIssuedAtToNow();
claims.setNotBeforeMinutesInThePast(2);
claims.setSubject("nim");
claims.setClaim("role", "tester");
JsonWebSignature jws = new JsonWebSignature();
jws.setPayload(claims.toJson());
jws.setKey(key.getPrivateKey());
jws.setKeyIdHeaderValue(key.getKeyId());
jws.setAlgorithmHeaderValue(AlgorithmIdentifiers.RSA_USING_SHA256);
String token = jws.getCompactSerialization();
System.out.printf("Generated Token [%s]\n", token);
JwtConsumer jwtConsumer = new JwtConsumerBuilder()
.setRequireExpirationTime() // the JWT must have an expiration time
.setAllowedClockSkewInSeconds(30) // allow some leeway in validating time based claims to account …
Run Code Online (Sandbox Code Playgroud) 我使用以下代码将证书转换为公钥并传递给 JwtConsumer:
jwt = "eU13VUDPQsLv2fvbCPEyeuQubditVOguIa2UWvaMhx2ES7cMlTL8F6IgplgpG_H7bXpduPnFUncn7zUYRXmvw_Bts8EfqICeGa5db6RGmofeA01OqowgCfxhWLwmU786riJIT0twMFe...............................BzR7DOvqsahbsx93yKqB_5Q";
// read public key from a file or config or something
String publicKeyPEM =
"-----BEGIN CERTIFICATE-----\n" +
"MIIFuDCCBKCgAwIBAgIQXQ/D2sE/XdZYvdViF83mMzANBgkqhkiG9w0BAQsFADB+\n" +
......................................................................................................... "saQRa7TBj6gAdlYwJVR+4hpLngANpwAG+bXHuEs+Ns/dE/s+b7aUb8/IJTWNtaaQ\n" +
"lMvr/4xtT6ZNCiaIM3uvIvzHqPxCn3sWa94FP9FIg3mbIia1ZbUx8NyMpETOjxaO\n" +
"X242VTjKf7mLCqibyn3kj93zZjgNa0AlbF/QdE9z4tQ58BwoDVlNK4mGv7Uq2nca\n" +
"2qTrgWcVVKyhKMnytiQ4LTs5O45R/YNbnEH7CA==\n" +
"-----END CERTIFICATE-----";
RsaKeyUtil rsaKeyUtil = new RsaKeyUtil();
PublicKey publicKey = rsaKeyUtil.fromPemEncoded(publicKeyPEM);
// create a JWT consumer
JwtConsumer jwtConsumer = new JwtConsumerBuilder()
.setRequireExpirationTime()
.setVerificationKey(publicKey)
.build();
// validate and decode the jwt
JwtClaims jwtDecoded = jwtConsumer.processToClaims(jwt);
Run Code Online (Sandbox Code Playgroud)
但是,在创建 PublicKey 实例时出现以下错误。
Starting Applicationjava.security.InvalidKeyException: IOException: ObjectIdentifier() -- data isn't an object ID …
Run Code Online (Sandbox Code Playgroud) jose4j ×12
java ×10
jwt ×9
encryption ×2
adal ×1
azure ×1
cryptography ×1
javascript ×1
jwe ×1
jwk ×1
node.js ×1
oauth-2.0 ×1
ssl ×1
x509 ×1