天天看点

jwt 私钥_jwt 用rsa公钥私钥进行验证

## JWT的主要应用场景

身份认证在这种场景下,一旦用户完成了登陆,在接下来的每个请求中包含JWT,可以用来验证用户身份以及对路由,服务和资源的访问权限进行验证。由于它的开销非常小,可以轻松的在不同域名的系统中传递,所有目前在单点登录(SSO)中比较广泛的使用了该技术。 信息交换在通信的双方之间使用JWT对数据进行编码是一种非常安全的方式,由于它的信息是经过签名的,可以确保发送者发送的信息是没有经过伪造的。

## JWT的结构

JWT包含了使用.分隔的三部分: Header 头部 Payload 负载 Signature 签名

其结构看起来是这样的Header.Payload.Signature

#### Header

在header中通常包含了两部分:token类型和采用的加密算法。{ "alg": "HS256", "typ": "JWT"} 接下来对这部分内容使用 **Base64Url** 编码组成了JWT结构的第一部分。

#### Payload

Token的第二部分是负载,它包含了claim, Claim是一些实体(通常指的用户)的状态和额外的元数据,有三种类型的claim:*reserved*, *public* 和 *private*.**Reserved claims**: 这些claim是JWT预先定义的,在JWT中并不会强制使用它们,而是推荐使用,常用的有 iss(签发者),exp(过期时间戳), sub(面向的用户), aud(接收方), iat(签发时间)。 **Public claims**:根据需要定义自己的字段,注意应该避免冲突 **Private claims**:这些是自定义的字段,可以用来在双方之间交换信息 负载使用的例子:{ "sub": "1234567890", "name": "John Doe", "admin": true} 上述的负载需要经过**Base64Url**编码后作为JWT结构的第二部分。

#### Signature

创建签名需要使用编码后的header和payload以及一个秘钥,使用header中指定签名算法进行签名。例如如果希望使用HMAC SHA256算法,那么签名应该使用下列方式创建: HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), secret) 签名用于验证消息的发送者以及消息是没有经过篡改的。 完整的JWT 完整的JWT格式的输出是以. 分隔的三段Base64编码,与SAML等基于XML的标准相比,JWT在HTTP和HTML环境中更容易传递。 下列的JWT展示了一个完整的JWT格式,它拼接了之前的Header, Payload以及秘钥签名:

## python发送数据

```

import calendar

import datetime

import time

import jenkins

import requests

import json

import logging

import configparser

import jwt

#read the private_key

with open('rsa_private_key.pem') as f:

private_key = f.read()

exp = datetime.datetime.utcnow() + datetime.timedelta(minutes=10)

exp = calendar.timegm(exp.timetuple())

# Generate the JWT

payload = {

# issued at time

'iat': int(time.time()),

# JWT expiration time (10 minute maximum)

'exp': exp,

# Integration's GitHub identifier

'iss': 'tom',

}

encoded = jwt.encode(payload, private_key, algorithm='RS256')

try:

headers = {

'content-type': "application/json",

'jwt': encoded

}

response = requests.post(server_url, headers=headers)

if response.status_code != 200:

logger.error("commit builds post go wrong , status code is : {}".format(response.status_code))

logger.error(response.text)

except Exception as e:

logger.error("commit builds post Error: {}".format(e))

```

## java接受数据(springboot拦截器)

```

public class WebInterceptor implements HandlerInterceptor {

static final Logger logger = LoggerFactory.getLogger(WebInterceptor.class);

@Autowired

private MyConfig myconfig;

@Override

public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {

logger.info("============== request before ==============");

String jwt = httpServletRequest.getHeader("jwt");

logger.info("jwt is : " + jwt);

String str = null;

if(myconfig == null){

WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext(httpServletRequest.getServletContext());

myconfig = wac.getBean(MyConfig.class);

}

try {

//read the public key

File file = ResourceUtils.getFile(myconfig.getRsaPublicKeyDir());

FileReader reader = new FileReader(file);

BufferedReader bReader = new BufferedReader(reader);

StringBuilder sb = new StringBuilder();

String s;

while ((s = bReader.readLine()) != null) {

sb.append(s);

}

bReader.close();

str = sb.toString();

RsaKeyUtil rsaKeyUtil = new RsaKeyUtil();

PublicKey publicKey = rsaKeyUtil.fromPemEncoded(str);

// create a JWT consumer

JwtConsumer jwtConsumer = new JwtConsumerBuilder()

.setRequireExpirationTime()

.setVerificationKey(publicKey)

//不能少不然会报错

.setRelaxVerificationKeyValidation()

.setJwsAlgorithmConstraints( // only allow the expected signature algorithm(s) in the given context

new AlgorithmConstraints(AlgorithmConstraints.ConstraintType.WHITELIST, // which is only RS256 here

AlgorithmIdentifiers.RSA_USING_SHA256))

.build();

// validate and decode the jwt

JwtClaims jwtDecoded = jwtConsumer.processToClaims(jwt);

Map jwtClaims = jwtDecoded.getClaimsMap();

Object iss = jwtClaims.get("iss");

logger.info("jwtClaims is : "+ jwtClaims);

}catch (Exception e){

logger.error(e.getMessage());

return false;

}

return true;

}

}

```