是否有为 JWK 创建指纹(又名指纹)的标准规范方法?
从我阅读的内容来看,标准似乎没有定义 akid
应该如何指定,我觉得这很奇怪。对我来说,它是最重要的,因为它是一个确定性的值,而不是一个需要查找表的值,这样其他人可以通过拥有公钥轻松地重新创建密钥 ID。
我知道 SSH 指纹和 X.509 指纹是标准化的,但是对于使用 JWK 的所有环境(尤其是浏览器)来说,这些似乎不是一个合适的解决方案,因为它们对于幼稚的实现来说太复杂了,并且包括能够操作的库这样(即伪造)会浪费大量内存、带宽和虚拟机编译时间。
官方称它为“指纹”而不是“指纹”。
在 C# 中,我需要针对 JWKS(代表如下键集的 Json 对象)验证不记名令牌
{
"keys":[
{
"e":"AQAB",
"kid":"unique key",
"kty":"RSA",
"n":"some value"
}
]
}
Run Code Online (Sandbox Code Playgroud) 当您向 OIDC 提供者进行身份验证时,您将获得一个 id 令牌,如果您为 API 指定了范围,您将获得一个访问令牌,以便客户端应用程序可以代表最终用户向受保护资源发出请求。通常,访问令牌也是 JWT。
但是如何阻止某人欺骗这些访问令牌之一,并创建一个并将其传递给 API?我知道有一些保护措施可以防止修改,因为签名将与任何验证逻辑预期的不同,但是如果恶意用户手动创建了一个全新的签名怎么办?特别是因为这些令牌可以通过任何需要访问令牌的 API 进行“就地”验证(并非所有 API 都使用自省端点......尤其是使用 JWT)。我确实了解 OpenID Connect 提供商提供的 JWT 签名密钥周围有元数据,并且它在 OIDC 发现文档中可用。例如,这里是Google 的 JWK 元数据. 鉴于您拥有公开的签名信息,并且无需向 OIDC 提供商发出任何请求即可验证 JWT 访问令牌,那么 JWT 的安全性如何?是什么阻止了一个人创建一个并将其作为不记名令牌传递给需要访问令牌的 API?
我需要将RSA公钥转换为有效的JWK。特别是JWK的值“ n”和“ e”是我正在努力解决的值。在https://tools.ietf.org/html/rfc7517#page-25上查看示例JWK时,编码似乎不正确。
目前,我的代码基本上如下所示:
private Map<String, Object> generateJWK(PublicKey publicKey){
RSAPublicKey rsa = (RSAPublicKey) publicKey;
Map<String, Object> values = new HashMap<>();
values.put("kty", rsa.getAlgorithm()); // getAlgorithm() returns kty not algorithm
values.put("kid", "someuniqueid");
values.put("n", Base64.encode(rsa.getModulus().toString()));
values.put("e", Base64.encode(rsa.getPublicExponent().toString()));
values.put("alg", "RS256");
values.put("use", "sig");
return values;
}
Run Code Online (Sandbox Code Playgroud)
但是,输出似乎未正确编码或e
类似以下内容:NjU1Mzc=
n
不包括特殊字符,如-
,_
和+
。:
jMzk1MNT0xTk2NED1xzzgNyQ00IykADzMAM0c0wz0M0MONj2z5TgNzI3yAM0OONYzzMjzwNzDxgAzxDxzMMAjTwNNDYMINMgNQDOEAkIM2jMQzkjUTDUYONNg1A00Tw1Nx4YEzAzjUT1MTNMjDjMM1MNNAjyTMIzxNADDINQANwT5yTDEMjEzNz2z2gOgjDDDNyNDjTzz43ETOYMI35gDjE00MYYM2DzDjDgww53Mwz0ME1NMgOM3MIzYTzMwzOMIQU5MjOzUjMNQNNg50U5NIDNzw2DMMOggNcQQM21TI5NMzDTN5Mj123O33MNNMkyNTNONxMM5wMMc04jTgAUE3MM1zMg4NNMT4MNDMM5yTO2j4jNDEMy1yNANNAzOIEUDzNwzExwTIkNjUjkN54Uz0DT5x0zM51k2MxYkx0zMNzxMkDUDTTQN3gAYODATQDDwMDMjMMcONjxMNTYMT5kgxNkMjNMQU0jzMEwIIMzTzUD4MgYDkDNzcAzN0TN4yNTz11DMxDUjDM2MyDMy4DEINMwT22QxjNNEzNDATy1OM1NNDxYgz5TxDkj3gQ32kIwNNkDO3xczDAENcTMNO0MOjTDwE3g11wNUcgNTwQk30kjjNNzTz4jTj4OOjQNYzMzcMjTQMkyzNNNUQOTOMMkMMMNzwNxDOEkg4xADIT4DNxMz2TENT4yN4z2I2zjyMU3DTOEQN4MIQjNDMU5Y11QkccwMNI0kNzyNjMMN4NMTTNMzMwxMjjDzgAANO1zwjYIEUjM1ADgDNjxTITMNNkIYxzyzzEEDMzDzNjzM4NjNNjc3ITTD0T5jzN=
Run Code Online (Sandbox Code Playgroud)
我是否正确假设值n和e均未正确编码?我应该如何将PublicKey转换为JWK?(不能使用第三方库)
我有一个 JWE,标头中有一个临时公钥。所以我有坐标X和Y。
我在 shell 模式下的问题是如何将 JWK 转换为 pem 格式的 ECC 公钥。
例如,这里有一个 jwk
{"epk":{"kty":"EC","crv":"P-256","x":"GCl--lQHb7NKYU3jXpKVI_BYaTlALT5JFPdl3sbB9mY","y":"ADRX25PBSlZJE79drET0ARtRqZAkUIMNt9aa2bbjBYY"}}
Run Code Online (Sandbox Code Playgroud)
当我这样做之后
> # I convert the x coordonate from base64url to base64
> echo -n -e "GCl++lQHb7NKYU3jXpKVI/BYaTlALT5JFPdl3sbB9mY" | base64 -d | hexdump
0000000 2918 fa7e 0754 b36f 614a e34d 925e 2395
0000010 58f0 3969 2d40 493e f714 de65 c1c6 66f6
0000020
> echo -n -e "ADRX25PBSlZJE79drET0ARtRqZAkUIMNt9aa2bbjBYY" | base64 -d | hexdump
0000000 3400 db57 c193 564a 1349 5dbf 44ac 01f4
0000010 511b 90a9 5024 0d83 d6b7 …
Run Code Online (Sandbox Code Playgroud) 我有一个 Laravel(Lumen) 登录 API,它使用 HS256 生成 JWT。然后我将不记名令牌发送到 Envoy Gateway 并从 Envoy 获取
JWT验证失败
在官方 JWT 解码网站上,我可以成功解码并验证我的不记名令牌。在这里我生成我的 JWT:
{
$payload = [
'iss' => config('app.name'), // Issuer vom Token
'sub' => strval($user->ID), // Subject vom Token
'username' => $user->username,
'iat' => time() - 500, // Time when JWT was issued.
'exp' => time() + config('jwt.ttl'), // Expiration time
'alg' => 'HS256',
'kid' => 'ek4Z9ouLmGnCoezntDXMxUwmjzNTBqptKNkfaqc6Ew8'
];
$secretKey = 'helloworld'; //my base64url
$jwtEnc = JWT::encode($payload, $secretKey, $payload['alg'], $payload['kid']);
return $jwtEnc;
}
Run Code Online (Sandbox Code Playgroud)
这是我的 Envoy …
我正在尝试使用 python 中的公钥来验证 idToken。
我首先将 JWK 令牌转换为 PEM,但当我调用“解码”函数时,我看到“签名验证失败”异常。我缺少什么?
# Long string goes here - this is the token to verify
myToken = 'ezFraWQiXXX.YYYYYYYY.ZZZZZZZZ'
# JWK Token
webkey = {
"alg": "RS256",
"e": "AQAB",
"kid": "d9FzOfniXuHf2sF3opIKZb0sW8Nuaa0d5d+AXXXXXXXX=",
"kty": "RSA",
"n": "nQwBvRlZKdXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX4HcenyO_WASyjr6korLEHxh8XXXXXXXXXXXX",
"use": "sig"
}
# Converting JWK to PEM
public_key = jwt.algorithms.RSAAlgorithm.from_jwk(webkey)
pubk_bytes = public_key.public_bytes(encoding=serialization.Encoding.PEM,format=serialization.PublicFormat.SubjectPublicKeyInfo)
# This is where I get the "signature verification failed" exception
claim = jwt.decode(myToken, pubk_bytes, algorithms=['RS256']) # <<-- ideally this should decode the token for me
Run Code Online (Sandbox Code Playgroud) 我有一个 JWT 安全令牌,需要通过 jwks 端点进行验证。jwks 中的数据如下所示:
{
"keys": [
{
"kty": "RSA",
"e": "AQAB",
"use": "sig",
"alg": "RS256",
"n": "......",
"kid": "2132132-b1e6-47e7-a30f-1831942f74bd"
},
{
"kty": "RSA",
"e": "AQAB",
"use": "sig",
"alg": "RS256",
"n": "......",
"kid": "tsp-app-a"
},
{
"kty": "RSA",
"e": "AQAB",
"use": "sig",
"alg": "RS256",
"n": ".....",
"kid": "tsp-app-b"
}
]
}
Run Code Online (Sandbox Code Playgroud)
我已经尝试了一个第三方 api,但它看起来依赖于 x5c 密钥,而我的案例中不存在该密钥。
我的代码是:
public static bool Validate(JwtSecurityToken jsonToken)
{
bool result = false;
try
{
var headers = Jose.JWT.Headers<JWTHeader>(jsonToken.RawData);
var payload = Jose.JWT.Payload<JWTPayload>(jsonToken.RawData);
string jwk …
Run Code Online (Sandbox Code Playgroud) "n": "rKZ-1zdz_CoLekSynOtyWv6cPSSkV28Kb9kZZHyYL-yhkKnH_bHl8OpWiGxQiKP0ulLRIaq1IhSMetkZ8FfXH-iptIDu4lPb8gt0HQYkjcy3HoaKRXBw2F8fJQO4jQ-ufR4l-E0HRqwLywzdtAImNWmju3A4kx8s0iSGHGSHyE4EUdh5WKt-NMtfUPfB5v9_2bC-w6wH7zAEsI5nscMXnvz1u8w7g2_agyhKSK0D9OkJ02w3I4xLMlrtKEv2naoBGerWckKcQ1kBYUh6WASPdvTqX4pcAJi7Tg6jwQXIP1aEq0JU8C0zE3d33kaMoCN3SenIxpRczRzUHpbZ-gk5PQ",
"e": "AQAB",
Run Code Online (Sandbox Code Playgroud)
如何从这些值生成公钥?最好通过 python 或 Linux 程序。如果由于值无效而导致问题毫无意义,我很抱歉。
源头就在这里。
更新我正在尝试使用下面的 x5c / x509 公钥值以编程方式验证 JWT 访问令牌。我可以通过将令牌和 x5c 值插入外部网站来实现此功能,但不能使用 JavaScript / jsrsasign 以编程方式进行。任何建议将不胜感激。
以下是 OIDC 提供商的公共 JSON Web 密钥集。
{
"keys": [
{
"kty": "RSA",
"kid": "server",
"use": "sig",
"alg": "RS256",
"n": "gLZO9w1OT_SWO-KbqiU0k3HevHggiY70XbDqgE1YaqhD-MwFUWNudExzF3oB28NYWYg5v6CJY0F-pUNtgukDM6ARDlh0n4xIvBRlnUnCTCx7pYOjpfXbTv49tlXmh4-ddh8EeQBLrF92u5UYs0tnZd8843mvYWohUNH1X1hM08-hpk7xCiy4XdwbeSlH757D2d5E0J0dGtZ744-dB2ZRCw2Vms_mk4Yyny4ifx2j2gIhikbb7WGmsTR2sWrtuhgZ_EBNUvrD0O54xbhQNTTFQ1pi9UZxo_gYc5Gp5fLcSOK6SDBKXbDS5hhy1vFyoa0xdgFv-xpem7YzmkKqzfjC9w",
"e": "AQAB",
"x5c": [
"MIIDMDCCAhigAwIBAgIEFIopYzANBgkqhkiG9w0BAQsFADBaMQkwBwYDVQQGEwAxCTAHBgNVBAgTADEJMAcGA1UEBxMAMQkwBwYDVQQKEwAxCTAHBgNVBAsTADEhMB8GA1UEAxMYZmNpc2Rldi5pY2UuaWJtY2xvdWQuY29tMB4XDTE4MTAwMTE4MTYyOFoXDTI4MDkyODE4MTYyOFowWjEJMAcGA1UEBhMAMQkwBwYDVQQIEwAxCTAHBgNVBAcTADEJMAcGA1UEChMAMQkwBwYDVQQLEwAxITAfBgNVBAMTGGZjaXNkZXYuaWNlLmlibWNsb3VkLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAIC2TvcNTk/0ljvim6olNJNx3rx4IImO9F2w6oBNWGqoQ/jMBVFjbnRMcxd6AdvDWFmIOb+giWNBfqVDbYLpAzOgEQ5YdJ+MSLwUZZ1Jwkwse6WDo6X1207+PbZV5oePnXYfBHkAS6xfdruVGLNLZ2XfPON5r2FqIVDR9V9YTNPPoaZO8QosuF3cG3kpR++ew9neRNCdHRrWe+OPnQdmUQsNlZrP5pOGMp8uIn8do9oCIYpG2+1hprE0drFq7boYGfxATVL6w9DueMW4UDU0xUNaYvVGcaP4GHORqeXy3EjiukgwSl2w0uYYctbxcqGtMXYBb/saXpu2M5pCqs34wvcCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAdtN9znA9a6luPAQurcQn8kJBlllslRWsNPMhPWpMtYaMLx6JhmDICGbaYZBGUboedwnUaEk6tE2b+EVlUE/tnaKVJms2cmCCFExQQrTHmRfFI/Vi/esVqAnz1E2dB61LMnQ2AeebXAZ/C7hRt1uXVboXr5Zokppr4FRS9QsjSK4dhcXxhfglTKJOPZ4dkSexhe6hybpL8XdGhoyf2SyNXCy5iYX0zQ5BmJaLimOcJyasZ/A7/YgsVbQyAe6Ubno6/sIUuOZ+J+snZsBSLViqcftGVPUkIWamv/yNQcEJrDWa4C+sr+9Yb7uFjuj4gDY0jvGkGmu53g0K8Vks+IfAdQ=="
],
"x5t#S256": "nTAGJuFFrm-vNBdkLVNmuePwTmlXr0T87IppgJPRT9k"
}
]
}
Run Code Online (Sandbox Code Playgroud)
这是我用来通过 x5c 验证访问令牌的代码。我的印象是我应该使用 x5c 值,但如果有其他方法对我来说没问题。只需要使用键下的上述值来验证令牌即可。
// break line every 64 characters.
x5cValue = x5cValue.replace(/(.{64})/g, "$1\n");
// base64 decode
var x5cValueAtob = atob(x5cValue);
// Add Begin / END certificate
x5cValue = "-----BEGIN CERTIFICATE-----\n" + x5cValueAtob + "\n-----END …
Run Code Online (Sandbox Code Playgroud) 目前,我正在尝试将通过 ECDH 生成的公钥/私钥对(表示为十六进制字符串)传递到importKey
Web Crypto API的函数中。
我从外部来源接收这些密钥,但我已经通过 node.js 生成了类似的密钥以进行测试。曲线是prime256v1
。作为参考,我用来测试我获得04b71388fced2daee34793f74a7dfa982e37ce539a728233bcadaec298fc4ee422165b8db13e657f9c7b27b35364f523ad11fab29d717606140cc6312ec2c685cc
的公钥是 ,私钥是4bd22700ec3450b5f27e47ba70c233a680c981ab02c1432a859ae23111bef377
。
const crypto = require('crypto');
const ecdh = crypto.createECDH('prime256v1');
ecdh.generateKeys();
console.log('ecdh p256 pubkey', ecdh.getPublicKey('hex'));
console.log('ecdh p256 prvkey', ecdh.getPrivateKey('hex'));
Run Code Online (Sandbox Code Playgroud)
通过raw
选项成功导入公钥importKey
。
const hexToUintArray = hex => {
const a = [];
for (let i = 0, len = hex.length; i < len; i += 2) {
a.push(parseInt(hex.substr(i, 2), 16));
}
return new Uint8Array(a);
}
const importedKey = await crypto.subtle.importKey(
'raw',
hexToUintArray('04b71388fced2daee34793f74a7dfa982e37ce539a728233bcadaec298fc4ee422165b8db13e657f9c7b27b35364f523ad11fab29d717606140cc6312ec2c685cc'),
{ …
Run Code Online (Sandbox Code Playgroud) 我正在阅读这篇关于 JWT 的博客,以及如何使用它的签名部分来验证令牌实际上是由受信任方颁发的。
https://hackernoon.com/json-web-tokens-jwt-demystified-f7e202249640
JSON Web Key (JWK) 是一个 JSON 对象,它包含一个众所周知的公钥,可用于验证已签名 JWT 的签名。
如果您的 JWT 的颁发者使用非对称密钥来签署 JWT,它可能会托管一个名为 JSON Web 密钥集 (JWKS) 的文件。JWKS 是一个包含属性键的 JSON 对象,而该键又包含一组 JWK 对象。
这是我的代码库中为我生成 JWT 的 Java 代码片段:
new JwtBuilder().setClaims(claims).setExpiration(expiration).signWith(signatureAlgorithm, sharedSecret).compact();
Run Code Online (Sandbox Code Playgroud)
我不太明白我如何获得 JWK 以及如何使用它们进行签名?我还没有在网上找到任何例子。
任何帮助将不胜感激。
当有人通过 Auth0 登录我的网站时,我会从 Auth0 获取 JWT 令牌。该令牌告诉我此人的 UID,并允许我从前端向后端进行 API 调用,在后端我可以验证 JWT 令牌以确保请求来自已登录的用户。
在https://jwt.io上,您可以粘贴任何 JWT 令牌,它会解析它并验证签名。
有谁知道我如何在 python 中做到这一点?
Auth0 没有给我 JWT 令牌的私钥,所以我无法使用jwt.decode()
.
相反,我需要以某种方式用它的公钥解析 JWT 令牌,但我不确定如何在 python 中检索它。
这是 JWT 令牌:
eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImZneF9xWEJVNWt0ZzZXSlNLdTJIdiJ9.eyJuaWNrbmFtZSI6ImpvaG5fbWFyayIsIm5hbWUiOiJqb2huX21hcmtAb3V0bG9vay5jb20iLCJwaWN0dXJlIjoiaHR0cHM6Ly9zLmdyYXZhdGFyLmNvbS9hdmF0YXIvNTMxZmJlZjcxN2I1NzVmYjU3MGJlYzcxNTBlOWQ4MTA_cz00ODAmcj1wZyZkPWh0dHBzJTNBJTJGJTJGY2RuLmF1dGgwLmNvbSUyRmF2YXRhcnMlMkZqby5wbmciLCJ1cGRhdGVkX2F0IjoiMjAyMi0wNC0wNVQxNDoyMzozNy42NTFaIiwiZW1haWwiOiJqb2huX21hcmtAb3V0bG9vay5jb20iLCJlbWFpbF92ZXJpZmllZCI6ZmFsc2UsImlzcyI6Imh0dHBzOi8vZGV2LW44Z2h5a3lvLnVzLmF1dGgwLmNvbS8iLCJzdWIiOiJhdXRoMHw2MTdiZTllMzJhMmYyNjAwNmEzZDlhM2EiLCJhdWQiOiIwUGwwR1F5cFhjNkZEakxhb0JuSjhzOEtNZjVKZ3J4bSIsImlhdCI6MTY0OTE2ODYyMiwiZXhwIjoxNjQ5MjA0NjIyLCJub25jZSI6IlJuTjBmbFoyU0Vkck4wSkhRV1EyY21FMk1rNUpXVlUzTW1jM2RtaHlXVkJWYm5oalowMUNUR1paU3c9PSJ9.NQBQPoEj6wzYzclrQzXAWh124gyg_Nf1UYZR4lAuqHZ-fdFycrBMA0Y0dBSvQ-WI7YZOMAPjCRK0nuxKzj9kMQ0c-3finCgsl411tX5tvaX_Khe116le_eyBV28aQQLjqT0zvLaSgIYaJqcgshQ1bYvJp8UXPf8GkMWCD89pnqYPwexx9nsWjrnikInLY9oSbWYN1zA7DxwhygI_JeQc6Cvu6pl1xq8m_WZaCMSOJS2umyl_7vfA84cDX1Zz8aVWEOMinnbmR48sY79cEiIMplcYJA3QH4yFEawSWbzWnVUcv9VCgCJ7fCbqikF86fz2TrWYrI6eATJoVHOXDNDKwA
Run Code Online (Sandbox Code Playgroud) jwk ×13
jwt ×8
rsa ×4
encryption ×2
java ×2
javascript ×2
python ×2
.net-core ×1
auth0 ×1
c# ×1
cryptography ×1
ecdsa ×1
envoyproxy ×1
lumen ×1
oauth-2.0 ×1
openssl ×1
public-key ×1
token ×1
validation ×1
x509 ×1