日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > python >内容正文

python

jwt私钥和公钥怎么获取_jwt 用rsa公钥私钥进行验证(python发送,java接受)

發(fā)布時(shí)間:2023/12/2 python 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 jwt私钥和公钥怎么获取_jwt 用rsa公钥私钥进行验证(python发送,java接受) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

JWT的主要應(yīng)用場景

身份認(rèn)證在這種場景下,一旦用戶完成了登陸,在接下來的每個(gè)請(qǐng)求中包含JWT,可以用來驗(yàn)證用戶身份以及對(duì)路由,服務(wù)和資源的訪問權(quán)限進(jìn)行驗(yàn)證。由于它的開銷非常小,可以輕松的在不同域名的系統(tǒng)中傳遞,所有目前在單點(diǎn)登錄(SSO)中比較廣泛的使用了該技術(shù)。 信息交換在通信的雙方之間使用JWT對(duì)數(shù)據(jù)進(jìn)行編碼是一種非常安全的方式,由于它的信息是經(jīng)過簽名的,可以確保發(fā)送者發(fā)送的信息是沒有經(jīng)過偽造的。

JWT的結(jié)構(gòu)

JWT包含了使用.分隔的三部分: Header 頭部 Payload 負(fù)載 Signature 簽名

其結(jié)構(gòu)看起來是這樣的Header.Payload.Signature

Header

在header中通常包含了兩部分:token類型和采用的加密算法。{ "alg": "HS256", "typ": "JWT"} 接下來對(duì)這部分內(nèi)容使用 Base64Url 編碼組成了JWT結(jié)構(gòu)的第一部分。

Payload

Token的第二部分是負(fù)載,它包含了claim, Claim是一些實(shí)體(通常指的用戶)的狀態(tài)和額外的元數(shù)據(jù),有三種類型的claim:reserved, public 和 private.Reserved claims: 這些claim是JWT預(yù)先定義的,在JWT中并不會(huì)強(qiáng)制使用它們,而是推薦使用,常用的有 iss(簽發(fā)者),exp(過期時(shí)間戳), sub(面向的用戶), aud(接收方), iat(簽發(fā)時(shí)間)。 Public claims:根據(jù)需要定義自己的字段,注意應(yīng)該避免沖突 Private claims:這些是自定義的字段,可以用來在雙方之間交換信息 負(fù)載使用的例子:{ "sub": "1234567890", "name": "John Doe", "admin": true} 上述的負(fù)載需要經(jīng)過Base64Url編碼后作為JWT結(jié)構(gòu)的第二部分。

Signature

創(chuàng)建簽名需要使用編碼后的header和payload以及一個(gè)秘鑰,使用header中指定簽名算法進(jìn)行簽名。例如如果希望使用HMAC SHA256算法,那么簽名應(yīng)該使用下列方式創(chuàng)建: HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), secret) 簽名用于驗(yàn)證消息的發(fā)送者以及消息是沒有經(jīng)過篡改的。 完整的JWT 完整的JWT格式的輸出是以. 分隔的三段Base64編碼,與SAML等基于XML的標(biāo)準(zhǔn)相比,JWT在HTTP和HTML環(huán)境中更容易傳遞。 下列的JWT展示了一個(gè)完整的JWT格式,它拼接了之前的Header, Payload以及秘鑰簽名:

encoded-jwt3.png

python發(fā)送數(shù)據(jù)

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接受數(shù)據(jù)(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)

//不能少不然會(huì)報(bào)錯(cuò)

.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;

}

}

簽名的目的

最后一步簽名的過程,實(shí)際上是對(duì)頭部以及載荷內(nèi)容進(jìn)行簽名。一般而言,加密算法對(duì)于不同的輸入產(chǎn)生的輸出總是不一樣的。對(duì)于兩個(gè)不同的輸入,產(chǎn)生同樣的輸出的概率極其地小(有可能比我成世界首富的概率還小)。所以,我們就把“不一樣的輸入產(chǎn)生不一樣的輸出”當(dāng)做必然事件來看待吧。

所以,如果有人對(duì)頭部以及載荷的內(nèi)容解碼之后進(jìn)行修改,再進(jìn)行編碼的話,那么新的頭部和載荷的簽名和之前的簽名就將是不一樣的。而且,如果不知道服務(wù)器加密的時(shí)候用的密鑰的話,得出來的簽名也一定會(huì)是不一樣的。

服務(wù)器應(yīng)用在接受到JWT后,會(huì)首先對(duì)頭部和載荷的內(nèi)容用同一算法再次簽名。那么服務(wù)器應(yīng)用是怎么知道我們用的是哪一種算法呢?別忘了,我們?cè)贘WT的頭部中已經(jīng)用alg字段指明了我們的加密算法了。

如果服務(wù)器應(yīng)用對(duì)頭部和載荷再次以同樣方法簽名之后發(fā)現(xiàn),自己計(jì)算出來的簽名和接受到的簽名不一樣,那么就說明這個(gè)Token的內(nèi)容被別人動(dòng)過的,我們應(yīng)該拒絕這個(gè)Token,返回一個(gè)HTTP 401 Unauthorized響應(yīng)。

信息會(huì)暴露?

是的。

所以,在JWT中,不應(yīng)該在載荷里面加入任何敏感的數(shù)據(jù)。在上面的例子中,我們傳輸?shù)氖怯脩舻腢ser ID。這個(gè)值實(shí)際上不是什么敏感內(nèi)容,一般情況下被知道也是安全的。

但是像密碼這樣的內(nèi)容就不能被放在JWT中了。如果將用戶的密碼放在了JWT中,那么懷有惡意的第三方通過Base64解碼就能很快地知道你的密碼了。

JWT的適用場景

我們可以看到,JWT適合用于向Web應(yīng)用傳遞一些非敏感信息。例如在上面提到的完成加好友的操作,還有諸如下訂單的操作等等。

其實(shí)JWT還經(jīng)常用于設(shè)計(jì)用戶認(rèn)證和授權(quán)系統(tǒng),甚至實(shí)現(xiàn)Web應(yīng)用的單點(diǎn)登錄。在下一次的文章中,我將為大家系統(tǒng)地總結(jié)JWT在用戶認(rèn)證和授權(quán)上的應(yīng)用。

總結(jié)

以上是生活随笔為你收集整理的jwt私钥和公钥怎么获取_jwt 用rsa公钥私钥进行验证(python发送,java接受)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。