傳輸密碼動態加密解密

傳輸密碼動態加密解密

這個模塊分離至上一篇api權限管理系統與前後端分離實踐,感覺那樣寫文章太長了找不到重點,分離出來要好點。


在用戶密碼登錄認證中,明文傳輸用戶輸入的密碼是不可取的。在沒有用https的情況下,這裏需要對用戶密碼加密傳輸,保證即使密碼泄露也不影響。

這裏的前後端加密解密下圖:

這裏寫圖片描述

由於介紹的是動態加密解密傳輸信息方案,這裏並不會涉及之後的JWT簽發等。

下面是實現細節:
angular 前端發送get動態祕鑰請求後會對對象進行監聽,在回調函數裏獲取後端返回的祕鑰後再進行加密處理,之後再發送登錄請求。在angular我把請求服務化了,下面的代碼片段會有點凌亂。

 // 調用獲取tokenKey祕鑰服務
    this.loginService.getTokenKey().subscribe(
      data => {
        this.responseData = data;
        if (this.responseData.data.tokenKey !== undefined) {
          const tokenKey = this.responseData.data.tokenKey;
          // 調用服務,發送認證請求
          this.loginService.login(this.appId, this.password, tokenKey).subscribe(
            data2 => {
              // 認證成功返回jwt
              this.responseData = data2;
              if (this.responseData.meta.code === 1003 && this.responseData.data.jwt != null) {
                this.authService.updateAuthorizationToken(this.responseData.data.jwt);
                this.authService.updateUid(this.appId);
                this.authService.updateUser(this.responseData.data.user);
                this.router.navigateByUrl('/index');
              } else {
                this.msg = '用戶名密碼錯誤';
                this.isDisabled = true;
              }
            },
            error => {
              console.error(error);
              this.msg = error;
              this.isDisabled = true;
            }
          );
        }
      }
    );
@Injectable()
export class LoginService {
  constructor(private httpUtil: HttpUtil) {
  }
  getTokenKey() {
    const url = 'account/login?tokenKey=get';
    // 先向後臺申請加密tokenKey tokenKey=get
    // const getKeyParam = new HttpParams().set('tokenKey', 'get');
    return this.httpUtil.get(url);
  }

  login(appId: string, password: string, tokenKey: string) {
    const url = 'account/login';
    tokenKey = CryptoJS.enc.Utf8.parse(tokenKey);
    password = CryptoJS.enc.Utf8.parse(password);
    password = CryptoJS.AES.encrypt(password, tokenKey, {mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.Pkcs7}).toString();
    console.log(password);
    const param = new HttpParams().append('appId', appId)
      .append('password', password)
      .append('methodName', 'login')
      .append('timestamp', new Date().toUTCString());
    return this.httpUtil.post(url, param);
  }
}

後端是在一個filter中對登錄註冊請求進行攔截,判斷其是正常登錄註冊還是獲取動態加密祕鑰請求,正常認證就走shiro,判斷爲獲取祕鑰則生成16隨機碼默認AES加密祕鑰爲約定16位,小於16位會報錯,將祕鑰以<遠程IP,祕鑰>的

 // 判斷若爲獲取登錄註冊加密動態祕鑰請求
        if (isPasswordTokenGet(request)) {
            //動態生成祕鑰,redis存儲祕鑰供之後祕鑰驗證使用,設置有效期5秒用完即丟棄
            String tokenKey = CommonUtil.getRandomString(16);
            try {
                redisTemplate.opsForValue().set("PASSWORD_TOKEN_KEY_"+request.getRemoteAddr().toUpperCase(),tokenKey,5, TimeUnit.SECONDS);
                // 動態祕鑰response返回給前端
                Message message = new Message();
                message.ok(1000,"issued tokenKey success")
                        .addData("tokenKey",tokenKey);
                RequestResponseUtil.responseWrite(JSON.toJSONString(message),response);

            }catch (Exception e) {
                LOGGER.warn(e.getMessage(),e);
                // 動態祕鑰response返回給前端
                Message message = new Message();
                message.ok(1000,"issued tokenKey fail");
                RequestResponseUtil.responseWrite(JSON.toJSONString(message),response);
            }
            return false;
        }
// 創建認證信息,其中就有包括獲取redis中對應IP的動態祕鑰
    private AuthenticationToken createPasswordToken(ServletRequest request) {
        Map<String ,String> map = RequestResponseUtil.getRequestParameters(request);
        String appId = map.get("appId");
        String timestamp = map.get("timestamp");
        String password = map.get("password");
        String host = request.getRemoteAddr();
        String tokenKey = redisTemplate.opsForValue().get("PASSWORD_TOKEN_KEY_"+host.toUpperCase());
        return new PasswordToken(appId,password,timestamp,host,tokenKey);
    }


效果展示

這裏寫圖片描述

這裏寫圖片描述

這裏寫圖片描述

這裏寫圖片描述

github:
bootshiro
usthe

碼雲:
bootshiro
usthe


持續更新。。。。。。

分享一波阿里雲代金券快速上雲

轉載請註明 from tomsun28

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章