如何向 JWE 添加过期时间?
How to add expiry to JWE?
我正在尝试将到期时间添加到我通过以下方式使用 jwcrypto 库生成的 JWE
from jwcrypto import jwe, jwk, jwt
from datetime import datetime, timedelta
import time
# create JWK from existing key
jwk_str = '{"k":"29Js2yXM6P_4v9K1mHDlYVHw8Xvm_GEhvMTvKTRLRzY","kty":"oct"}'
jwk_key = jwk.JWK.from_json(jwk_str)
# calculate expiry time
d = datetime.now() + timedelta(seconds=5)
epoch = datetime.utcfromtimestamp(0)
total_seconds = (d - epoch).total_seconds()
# Add exp to the claims
claims={"exp": total_seconds, "sub": "Some random payload"}
print(claims)
jwttoken = jwt.JWT(header={"alg": "A256KW", "enc": "A256CBC-HS512"}, claims=claims)
jwttoken.make_encrypted_token(jwk_key)
jwetokenstr = jwttoken.serialize()
print(jwetokenstr)
# wait for 10 seconds to cross the expiry time
time.sleep(10)
jwttoken = jwt.JWT()
jwttoken.deserialize(token, jwk_key) # Ideally this line should fail as expiry is reached but it doesn't
print(jwttoken.claims)
我正在获取有效负载,但未读取过期声明并且不会在过期时失败。
我做错了什么?
这最终归结为日期时间操作错误。
JSON 网络令牌的 exp
声明应填写从过期时间开始的秒数。
datetime.now()
returns 一个 本地时间 (不是 UTC 时间) datetime.datetime
对象。上面的代码然后继续从 0 纪元时间的 UTC 时间 datetime.datetime
对象中减去这个本地时间 datetime.datetime
对象,并计算这两者之间的总秒数以确定到期时间。 但是,因为这是比较本地时间日期时间和UTC时间日期时间,秒数这里实际上是你的本地时区与 UTC 差异的常数因子。
例如,如果我住在一个时间比 UTC 早 5 小时的地方,我实际上会使用一个比我想要的真实纪元时间差 5 * 60 * 60
秒的纪元时间作为到期时间使用此代码。
相反,您可以简单地使用 round(time.time()) + x
,其中 x
是未来 JWT 到期的秒数。 time.time()
returns 从纪元算起的秒数(但作为浮点数,所以你需要四舍五入)。
例如:
from jwcrypto import jwe, jwk, jwt
from datetime import datetime, timedelta
import time
jwk_str = '{"k":"29Js2yXM6P_4v9K1mHDlYVHw8Xvm_GEhvMTvKTRLRzY","kty":"oct"}'
jwk_key = jwk.JWK.from_json(jwk_str)
jwt_valid_seconds = 3
expiry_time = round(time.time()) + jwt_valid_seconds
claims={"exp": expiry_time, "sub": "Some random payload"}
jwttoken = jwt.JWT(header={"alg": "A256KW", "enc": "A256CBC-HS512"}, claims=claims)
jwttoken.make_encrypted_token(jwk_key)
jwetokenstr = jwttoken.serialize()
jwttoken2 = jwt.JWT()
jwttoken2.deserialize(jwetokenstr, jwk_key)
print('This should succeed because we are deserializing immediately before the JWT has expired:')
print(jwttoken2.claims)
# Wait for the JWT to expire, and then extra time for the leeway.
leeway = 60
time.sleep(leeway + jwt_valid_seconds + 1)
jwttoken2 = jwt.JWT()
print('\nThis should fail due to the JWT expiring:')
jwttoken2.deserialize(jwetokenstr, jwk_key)
给出输出
(env) $ python jwe_expiry.py
This should succeed because we are deserializing immediately before the JWT has expired:
{"exp":1576737332,"sub":"Some random payload"}
This should fail due to the JWT expiring:
Traceback (most recent call last):
File "jwe_expiry.py", line 26, in <module>
jwttoken2.deserialize(jwetokenstr, jwk_key)
File "... python3.7/site-packages/jwcrypto/jwt.py", line 493, in deserialize
self._check_provided_claims()
File "... python3.7/site-packages/jwcrypto/jwt.py", line 370, in _check_provided_claims
self._check_default_claims(claims)
File "... python3.7/site-packages/jwcrypto/jwt.py", line 351, in _check_default_claims
self._check_exp(claims['exp'], time.time(), self._leeway)
File "... python3.7/site-packages/jwcrypto/jwt.py", line 333, in _check_exp
claim, limit, leeway))
jwcrypto.jwt.JWTExpired: Expired at 1576737332, time: 1576737392(leeway: 60)
我正在尝试将到期时间添加到我通过以下方式使用 jwcrypto 库生成的 JWE
from jwcrypto import jwe, jwk, jwt
from datetime import datetime, timedelta
import time
# create JWK from existing key
jwk_str = '{"k":"29Js2yXM6P_4v9K1mHDlYVHw8Xvm_GEhvMTvKTRLRzY","kty":"oct"}'
jwk_key = jwk.JWK.from_json(jwk_str)
# calculate expiry time
d = datetime.now() + timedelta(seconds=5)
epoch = datetime.utcfromtimestamp(0)
total_seconds = (d - epoch).total_seconds()
# Add exp to the claims
claims={"exp": total_seconds, "sub": "Some random payload"}
print(claims)
jwttoken = jwt.JWT(header={"alg": "A256KW", "enc": "A256CBC-HS512"}, claims=claims)
jwttoken.make_encrypted_token(jwk_key)
jwetokenstr = jwttoken.serialize()
print(jwetokenstr)
# wait for 10 seconds to cross the expiry time
time.sleep(10)
jwttoken = jwt.JWT()
jwttoken.deserialize(token, jwk_key) # Ideally this line should fail as expiry is reached but it doesn't
print(jwttoken.claims)
我正在获取有效负载,但未读取过期声明并且不会在过期时失败。 我做错了什么?
这最终归结为日期时间操作错误。
JSON 网络令牌的 exp
声明应填写从过期时间开始的秒数。
datetime.now()
returns 一个 本地时间 (不是 UTC 时间) datetime.datetime
对象。上面的代码然后继续从 0 纪元时间的 UTC 时间 datetime.datetime
对象中减去这个本地时间 datetime.datetime
对象,并计算这两者之间的总秒数以确定到期时间。 但是,因为这是比较本地时间日期时间和UTC时间日期时间,秒数这里实际上是你的本地时区与 UTC 差异的常数因子。
例如,如果我住在一个时间比 UTC 早 5 小时的地方,我实际上会使用一个比我想要的真实纪元时间差 5 * 60 * 60
秒的纪元时间作为到期时间使用此代码。
相反,您可以简单地使用 round(time.time()) + x
,其中 x
是未来 JWT 到期的秒数。 time.time()
returns 从纪元算起的秒数(但作为浮点数,所以你需要四舍五入)。
例如:
from jwcrypto import jwe, jwk, jwt
from datetime import datetime, timedelta
import time
jwk_str = '{"k":"29Js2yXM6P_4v9K1mHDlYVHw8Xvm_GEhvMTvKTRLRzY","kty":"oct"}'
jwk_key = jwk.JWK.from_json(jwk_str)
jwt_valid_seconds = 3
expiry_time = round(time.time()) + jwt_valid_seconds
claims={"exp": expiry_time, "sub": "Some random payload"}
jwttoken = jwt.JWT(header={"alg": "A256KW", "enc": "A256CBC-HS512"}, claims=claims)
jwttoken.make_encrypted_token(jwk_key)
jwetokenstr = jwttoken.serialize()
jwttoken2 = jwt.JWT()
jwttoken2.deserialize(jwetokenstr, jwk_key)
print('This should succeed because we are deserializing immediately before the JWT has expired:')
print(jwttoken2.claims)
# Wait for the JWT to expire, and then extra time for the leeway.
leeway = 60
time.sleep(leeway + jwt_valid_seconds + 1)
jwttoken2 = jwt.JWT()
print('\nThis should fail due to the JWT expiring:')
jwttoken2.deserialize(jwetokenstr, jwk_key)
给出输出
(env) $ python jwe_expiry.py
This should succeed because we are deserializing immediately before the JWT has expired:
{"exp":1576737332,"sub":"Some random payload"}
This should fail due to the JWT expiring:
Traceback (most recent call last):
File "jwe_expiry.py", line 26, in <module>
jwttoken2.deserialize(jwetokenstr, jwk_key)
File "... python3.7/site-packages/jwcrypto/jwt.py", line 493, in deserialize
self._check_provided_claims()
File "... python3.7/site-packages/jwcrypto/jwt.py", line 370, in _check_provided_claims
self._check_default_claims(claims)
File "... python3.7/site-packages/jwcrypto/jwt.py", line 351, in _check_default_claims
self._check_exp(claims['exp'], time.time(), self._leeway)
File "... python3.7/site-packages/jwcrypto/jwt.py", line 333, in _check_exp
claim, limit, leeway))
jwcrypto.jwt.JWTExpired: Expired at 1576737332, time: 1576737392(leeway: 60)