API安全
數(shù)據(jù)準(zhǔn)備
header:
time:時間戳
token:用戶登錄信息token jwt
version:版本
did:設(shè)備號
......
body:
name:gaozhan
......
客戶端加密
1.生成隨機AES加密字符串a(chǎn)es_key
2.aes_key對header內(nèi)容加密 aes_header
3.aes_key對body內(nèi)容加密 aes_body
4.rsa公鑰對aes_key進(jìn)行加密 rsa_aes_key
傳輸
0.rsa_aes_key放入header
1.aes_header放入header
2.aes_body 放body
服務(wù)端解密
0.RSA私鑰對rsa_aes_key解密 得到aes_key
1.aes_key對header解密
2.校驗時間戳?xí)r效性/版本有效性/用戶訪問權(quán)限
3.aes_key對aes_body解密
代碼示例
github: https://github.com/gaozhan3253/app-restful-api-demo
片段
laravel中間件:
//獲取rsa_aes_key
$rsa_aes_key=$request->header('rsa-aes-key');
//不存在rsa加密字符串時
if(empty($rsa_aes_key)) {
return response()->json(['message'=>'非法訪問','status_code'=>401],401);
}
//解密rsa加密字符串 得到aes加密字符串
$aes_key= RsaOptions::decrypt($rsa_aes_key);
if(empty($aes_key)) {
return response()->json(['message'=>'非法訪問','status_code'=>401],401);
}
//接收aes加密的header
$aes_header=$request->header('aes-header');
if(empty($aes_header)) {
return response()->json(['message'=>'無加密header信息','status_code'=>401],401);
}
//解密aes加密字符串
$headers= AesOptions::aes128cbcDecrypt($aes_header,$aes_key);
$headers=json_decode($headers);
//驗證是否存在必須time字段 因為time字段絕對存在
if(empty($headers) ||empty($headers->time)) {
return response()->json(['message'=>'無效header','status_code'=>401],401);
}
//驗證唯一性
$onlyToken=$headers->onlytoken;
//$onlyToken=$headers->onlytoken.rand(000001,999999);//測試用 唯一性處理
$onlyTokenHasBool= Cache::store('redis')->has($onlyToken);
if($onlyTokenHasBool) {
return response()->json(['message'=>'重復(fù)請求','status_code'=>401],401);
}else{
Cache::store('file')->put($onlyToken,'',5);
}
//驗證時效性
$requestTime=$headers->time;//請求的時間戳
$expiresTime=strtotime('-'. env('API_EXPIRES_TIME',1) .' minute');//請求有效時間
if($expiresTime>$requestTime) {
return response()->json(['message'=>'請求已過期','status_code'=>401],401);
}
//將aes_key保存 用于將返回信息加密
define('AES_KEY',$aes_key);
//將解密后的header寫回header中
if(count($headers)){
foreach($headers as $key=>$value){
//jwt驗證token格式化處理
if($key=='token'){
$key='authorization';
$value='bearer '.$value;
}
$request->headers->set($key,$value);
}
}
//獲取body
$aes_body=$request->get('aes-body','');
//解密aes加密字符串
$bodys= AesOptions::aes128cbcDecrypt($aes_body,$aes_key);
$bodys=json_decode($bodys);
if(count($bodys)){
foreach($bodys as $key=>$value){
$request->offsetSet($key,$value);
}
}