JWT登入資訊加密
阿新 • • 發佈:2018-12-25
1、背景
對於傳統的單點登入系統,使用cookie和session的方式儲存使用者登入資訊,但是對於安全性要求較高的企業–金融企業,就需要對使用者的資訊進行加密儲存,防止客戶資訊洩露。
2、JWT構成
JWT—-JSON Web Token
第一部分我們稱它為頭部(header)
完整的頭部就像下面這樣的JSON:
{
"typ": "JWT", //宣告型別,這裡是jwt
"alg": "HS256" //宣告加密的演算法 通常直接使用 HMAC SHA256
}
第二部分我們稱其為載荷(payload)
載荷就是存放有效資訊的地方。 這個名字像是特指飛機上承載的貨品,這些有效資訊包含三個部分 標準中註冊的宣告 公共的宣告 私有的宣告
標準中註冊的宣告 (建議但不強制使用) :
iss: jwt簽發者
sub: jwt所面向的使用者
aud: 接收jwt的一方
exp: jwt的過期時間,這個過期時間必須要大於簽發時間
nbf: 定義在什麼時間之前,該jwt都是不可用的.
iat: jwt的簽發時間
jti: jwt的唯一身份標識,主要用來作為一次性token,從而回避重放攻擊。
公共的宣告 :
公共的宣告可以新增任何的資訊,一般新增使用者的相關資訊或其他業務需要的必要資訊.但不建議新增敏感資訊,因為該部分在客戶端可解密.
私有的宣告 :
私有宣告是提供者和消費者所共同定義的宣告,一般不建議存放敏感資訊,因為base64是對稱解密的,意味著該部分資訊可以歸類為明文資訊。
定義一個payload:
{
"name" :"MiChong",
"age":"23",
"org":"天王蓋地虎"
}
第三部分是簽證(signature)
jwt的第三部分是一個簽證資訊,這個簽證資訊由三部分組成:
header (base64後的)
payload (base64後的)
secret
3、Java實現
新增依賴
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId >
<version>3.3.0</version>
</dependency>
加密解密實現
package cn.buildworld.daliy;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import java.io.UnsupportedEncodingException;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
/**
* jwt加密解密工具
*
* @Author MiChong
* @Email: [email protected]
* @Create 2018-04-11 16:16
* @Version: V1.0
*/
public class JwtToken {
/**
* 公共金鑰
*/
public static final String SECRET = "michong";
/**
* 建立token
* @return
* @throws UnsupportedEncodingException
*/
public static String createToken() throws UnsupportedEncodingException {
//簽發時間
Date date = new Date();
//過期時間- 1分鐘過期
Calendar nowTime = Calendar.getInstance();
nowTime.add(Calendar.MINUTE,1);
Date expiresDate = nowTime.getTime();
Map<String,Object> map = new HashMap<>();
map.put("alg","HS256");
map.put("typ","JWT");
String token = JWT.create()
.withClaim("name", "michong")
//設定過期時間
.withExpiresAt(expiresDate)
//設定簽發時間
.withIssuedAt(date)
.sign(Algorithm.HMAC256(SECRET));
return token;
}
/**
* 解密
* @param token
* @return
* @throws UnsupportedEncodingException
*/
public static Map<String,Claim> verifyToken(String token) throws UnsupportedEncodingException {
JWTVerifier verifier = JWT.require(Algorithm.HMAC256(SECRET))
.build();
DecodedJWT jwt = null;
try{
//解密
jwt = verifier.verify(token);
}catch (Exception e){
throw new RuntimeException("token已經失效");
}
return jwt.getClaims();
}
}
四、測試
public class Auth0WithJWT {
public static void main(String[] args) throws UnsupportedEncodingException {
String token = JwtToken.createToken();
System.out.println(token);
Map<String, Claim> stringClaimMap = JwtToken.verifyToken(token);
System.out.println(stringClaimMap.get("name").asString());
}
}