JSON 网络令牌 (JWT)
JSON Web Token (JWT)
我有一个关于 JSON Web 令牌 (JWT) 的一般性问题。
如果 JWT 通过黑客攻击或物理访问从客户端窃取(例如,它被存储为 cookie 或应用程序的数据库),它可用于发送到服务器认为它是合法用户。这是正确的吗?
是否有任何通用或标准的做法来防止这种情况,例如,通过从客户端发送 device/browser 的类型或一些参考代码,服务器检查它是否与 JWT 令牌所使用的其他数据相匹配生成并存储。 (但是,我读到标准做法是不在服务器上存储任何内容。)
请告知,因为我需要实施 Java JWT (JJWT)、RESTful Java Jersey 和 Google Web Toolkit。 (我一直在阅读这样的文档:[https://stormpath.com/blog/where-to-store-your-jwts-cookies-vs-html5-web-storage])。
谢谢!
在客户端构建 JWT,如:
byte[] key = getSignatureKey();
String jwt = Jwts.builder().setIssuer("myTestApplication")
.setSubject("myTest")
.setExpiration(expirationDate)
.put("scope", "testing")
.signWith(SignatureAlgorithm.HS256, key)
.compact();
在服务器端,您可以验证 JWT 关于 key 和 expiration date exp
(以及更多,即创建日期、发行者 iss
、受众 aud
):
String subject = "notMyToken";
try {
Jws jwtClaims = Jwts.parser().setSigningKey(key).parseClaimsJws(jwt);
subject = claims.getBody().getSubject();
//OK, we can trust this JWT
} catch (SignatureException e) {
//don't trust the JWT!
}
窃取 JWT 应该通过使用 SSL 来避免,...但是如果 JWT 被盗,将有重放这个 JWT 的风险 - 对。这就是 jti
的用武之地。
The jti (JWT ID) claim provides a unique identifier for the JWT. The
identifier value MUST be assigned in a manner that ensures that there
is a negligible probability that the same value will be accidentally
assigned to a different data object; if the application uses multiple
issuers, collisions MUST be prevented among values produced by
different issuers as well. The jti claim can be used to prevent the
JWT from being replayed. The jti value is a case-sensitive string. Use
of this claim is OPTIONAL.
有了这个标识符,你可以识别这个 ID 是否已经发送(你必须在服务器端将它列入黑名单,这在某种程度上破坏了 JWT 的本质)。因为您应该使用到期日期,所以如果到期日期导致 SignatureException,您可以清除 ID。
但是,如果 'hacker' 从数据库中窃取了 JWT,正如您在问题中所写,除了被盗的 JWT 之外,您可能还有其他问题,因为攻击者还可能窃取其他数据等。
希望对您有所帮助。
拥有 JWT 是身份验证的证明。窃取令牌的攻击者可以冒充用户。
因此,确保令牌安全:
- 使用 TLS 通道
- 根据存储类型添加额外的安全措施。 Cookie 容易受到 CSRF 攻击。如果您不需要从 javascript 访问令牌,请使用 HttpOnly。 LocalStorage 容易受到 XSS 攻击
- 为身份验证令牌设置较短的过期时间,如果令牌过期则需要凭据
黑名单没有用,因为您不会知道 JWT 已被盗。而且它的用法打破了无状态性,这是 JWT
的优点之一
此外还可以将 IP 添加到令牌中,但请考虑使用场景,因为它在代理后面的移动设备或系统上可能会出现问题
我有一个关于 JSON Web 令牌 (JWT) 的一般性问题。
如果 JWT 通过黑客攻击或物理访问从客户端窃取(例如,它被存储为 cookie 或应用程序的数据库),它可用于发送到服务器认为它是合法用户。这是正确的吗?
是否有任何通用或标准的做法来防止这种情况,例如,通过从客户端发送 device/browser 的类型或一些参考代码,服务器检查它是否与 JWT 令牌所使用的其他数据相匹配生成并存储。 (但是,我读到标准做法是不在服务器上存储任何内容。)
请告知,因为我需要实施 Java JWT (JJWT)、RESTful Java Jersey 和 Google Web Toolkit。 (我一直在阅读这样的文档:[https://stormpath.com/blog/where-to-store-your-jwts-cookies-vs-html5-web-storage])。
谢谢!
在客户端构建 JWT,如:
byte[] key = getSignatureKey();
String jwt = Jwts.builder().setIssuer("myTestApplication")
.setSubject("myTest")
.setExpiration(expirationDate)
.put("scope", "testing")
.signWith(SignatureAlgorithm.HS256, key)
.compact();
在服务器端,您可以验证 JWT 关于 key 和 expiration date exp
(以及更多,即创建日期、发行者 iss
、受众 aud
):
String subject = "notMyToken";
try {
Jws jwtClaims = Jwts.parser().setSigningKey(key).parseClaimsJws(jwt);
subject = claims.getBody().getSubject();
//OK, we can trust this JWT
} catch (SignatureException e) {
//don't trust the JWT!
}
窃取 JWT 应该通过使用 SSL 来避免,...但是如果 JWT 被盗,将有重放这个 JWT 的风险 - 对。这就是 jti
的用武之地。
The jti (JWT ID) claim provides a unique identifier for the JWT. The identifier value MUST be assigned in a manner that ensures that there is a negligible probability that the same value will be accidentally assigned to a different data object; if the application uses multiple issuers, collisions MUST be prevented among values produced by different issuers as well. The jti claim can be used to prevent the JWT from being replayed. The jti value is a case-sensitive string. Use of this claim is OPTIONAL.
有了这个标识符,你可以识别这个 ID 是否已经发送(你必须在服务器端将它列入黑名单,这在某种程度上破坏了 JWT 的本质)。因为您应该使用到期日期,所以如果到期日期导致 SignatureException,您可以清除 ID。
但是,如果 'hacker' 从数据库中窃取了 JWT,正如您在问题中所写,除了被盗的 JWT 之外,您可能还有其他问题,因为攻击者还可能窃取其他数据等。
希望对您有所帮助。
拥有 JWT 是身份验证的证明。窃取令牌的攻击者可以冒充用户。
因此,确保令牌安全:
- 使用 TLS 通道
- 根据存储类型添加额外的安全措施。 Cookie 容易受到 CSRF 攻击。如果您不需要从 javascript 访问令牌,请使用 HttpOnly。 LocalStorage 容易受到 XSS 攻击
- 为身份验证令牌设置较短的过期时间,如果令牌过期则需要凭据
黑名单没有用,因为您不会知道 JWT 已被盗。而且它的用法打破了无状态性,这是 JWT
的优点之一此外还可以将 IP 添加到令牌中,但请考虑使用场景,因为它在代理后面的移动设备或系统上可能会出现问题