1. 程式人生 > >JWT登入資訊加密

JWT登入資訊加密

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());
    }
}
結果