數(shù)據(jù)加密
hashlib數(shù)據(jù)加密
用于加密的相關(guān)操作,代替MD5模塊和sha模塊,主要提供SHA1,SHA224,SHA256,SHA384,SHA512算法。
要想使用它,要先導(dǎo)入hashlib模塊。
import hashlib
-
簡(jiǎn)單加密:
psw = "12345"
temp = hashlib.sha1(psw.encode()) # HASA類型 <sha1 HASH object @ 0x00000216D30FF7D8>
print(temp.hexdigest) # 返回16進(jìn)制字符串
- hash加鹽加密
導(dǎo)入加密函數(shù)
from werkzeug.security import generate_password_hash, check_password_hash-
密碼生成函數(shù)generate_password_hash
temp = generate_password_hash(password, method = "pbkdf2:sha1:200", salt_length = 8)參數(shù)說明:
- password: 明文密碼
- method: 哈希加密的方法,格式為pdpdf2:<method>[:iterations]
- method: 哈希的方式, 一般為SHA1
- iterations: (可選參數(shù)) 迭代次數(shù),默認(rèn)為1000
- salt_length: 鹽值的長(zhǎng)度,默認(rèn)為8
加密后的字符串:
method$salt$hash
- 密碼驗(yàn)證函數(shù): check_password_hash
check_password_hash(pwhash, password)
定義參數(shù):
pwhash: generate_password_hash 生成的哈希字符串
password: 需要驗(yàn)證的明文密碼
check_password_hash 函數(shù)用于驗(yàn)證經(jīng)過generate_password_hash加密過的密碼;
若密碼匹配,則返回真,否則返回假。
token(jwt)令牌
站在主流的框架都已經(jīng)實(shí)現(xiàn)了前后端分離,為什么呢?
- 可以讓前后端的工作分工更明確,不需要在視圖模板中加入很多{%XXX%}標(biāo)簽
- 為了適應(yīng)跨域調(diào)用或者多客戶端調(diào)用。例如:手機(jī)應(yīng)用調(diào)用的接口大都是第三方API。
雖然flask有json支持,但是對(duì)象轉(zhuǎn)化是一大問題;所以整合JWT,讓框架具有更多的適應(yīng)性。JWT就是基于token的權(quán)限驗(yàn)證。
什么是token???
Json Web Token(JWT)是為了網(wǎng)絡(luò)應(yīng)用環(huán)境間傳遞聲明而執(zhí)行的一種基于JSON的開發(fā)標(biāo)準(zhǔn),該token被設(shè)計(jì)的緊湊且安全,特別適用于分布式站點(diǎn)的單點(diǎn)登錄(SSO)場(chǎng)景。
JWT的聲明一般被用來在身份提供者和服務(wù)提供者見傳遞被認(rèn)證的用戶身份信息,以便于從資源服務(wù)器獲取資源,也可以增加一些額外的其他業(yè)務(wù)邏輯所必須的生命信息。該token也可以直接被用于認(rèn)證,也可以被加密。
token的工作流程:
1. 用戶使用用戶信息請(qǐng)求服務(wù)器
2. 服務(wù)器驗(yàn)證用戶信息
3. 服務(wù)器向通過驗(yàn)證的用戶發(fā)送一個(gè)token
4. 客戶端存儲(chǔ)token, 并且在之后的每次請(qǐng)求時(shí)附加這個(gè)token值
5. 服務(wù)器驗(yàn)證token,并且返回對(duì)應(yīng)數(shù)據(jù)。
token必須要在每次請(qǐng)求時(shí)發(fā)送給服務(wù)器,它應(yīng)該保存在請(qǐng)求頭中,并且服務(wù)器要支持CORS(跨域資源共享)策略,一般我們?cè)诜?wù)器中執(zhí)行如下操作:
Access-Control-Allow-Origin:*
JWT 構(gòu)成
JWT是由三部分構(gòu)成,各部分之間通過“.”來分隔。
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJVc2VySWQiOjEyMywiVXNlck5hbWUiOiJhZG1pbiJ9.Qjw1epD5P6p4Yy2yju3-fkq28PddznqRj3ESfALQy_U
第一部分:頭部(header)
第二部分:荷載(payload)
第三部分:簽證(signature)
-
header
頭部承載了兩部分信息:- 聲明類型(jwt)
- 聲明加密算法:(通常直接使用HMAC SHA256)
完整的頭部信息示例:
"typ":"JWT",
"alg":"HS256"
然后將頭部進(jìn)行base64加密構(gòu)成第一部分。
-
plyload
荷載用來存放有效信息,包含三個(gè)部分:- 標(biāo)準(zhǔn)中注冊(cè)的聲明
- 公共的聲明
- 私有的聲明
標(biāo)注中注冊(cè)的聲明
iss: jwt簽發(fā)者
sub: jwt所面向的用戶
aud: 接收jwt的一方
exp: jwt的過期時(shí)間,這個(gè)過期時(shí)間必須大于簽發(fā)時(shí)間
nbf: 定義在什么時(shí)間之前,該jwt都是不可用的
iat: jwt的簽發(fā)時(shí)間
jti: jwt的唯一身份標(biāo)識(shí),主要用來作為一次性token,從而回避重放攻擊
公共的聲明:
公共的聲明可以添加任何信息,一般添加用戶的相關(guān)信息或其它業(yè)務(wù)需要的必要信息,但是不建議添加敏感信息,因?yàn)樵摽蛻舳丝山饷埽?br> 私有的聲明:
私有的聲明是提供者和消費(fèi)者功能定義的聲明,一般不建議存放敏感信息,因?yàn)閎ase64是對(duì)稱解密的,意味著該部分信息可以歸類為明文信息。
# 定義一個(gè)payload payload = { "sub":"123456789", "name":"John Doe", "admin":true }
然后將其base64加密,得到j(luò)wt的第二部分。
signature
jwt的第三部分是簽證信息,它由三部分組成:
header(base64后的)
-
payload(base64后的)
secred
這個(gè)部分需要base64加密后的header和base64加密后的payload使用“.”連接組成的字符串,然后通過header中聲明的加密方式進(jìn)行secret組合加密,然后構(gòu)成了jwt的第三部分。var encodedString = base64UrlEncode(header) + '.' + base64UrlEncode(payload);
var signature = HMACSHA256(encodedString, 'secret'); // TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ
注意:
secret是保存在服務(wù)器端的,jwt的簽發(fā)也是在服務(wù)器端的,secret就是用來進(jìn)行jwt的簽發(fā)和jwt的驗(yàn)證,所以它就是你服務(wù)端的私鑰,在任何場(chǎng)景都不應(yīng)該泄露出去。
總結(jié)
優(yōu)點(diǎn):
因?yàn)閖son的通用性,所以JWT是可以跨語言支持的,像C#,JavaScript,NodeJS,PHP等許多語言都可以使用
因?yàn)橛闪藀ayload部分,所以JWT可以在自身存儲(chǔ)一些其它業(yè)務(wù)邏輯所必要的非敏感信息
便于傳輸,jwt的構(gòu)成非常簡(jiǎn)單,字節(jié)占用很小,所以它是非常便于傳輸?shù)?/p>
它不需要在服務(wù)端保存會(huì)話信息,所以它易于應(yīng)用的擴(kuò)展
安全相關(guān)
不應(yīng)該在jwt的payload部分存儲(chǔ)敏感信息,因?yàn)樵摬糠质强蛻舳丝山饷艿牟糠?/p>
保護(hù)好secret私鑰。該私鑰非常重要
如果可以,請(qǐng)使用https協(xié)議