做者:ksfzhaohuijava
my.oschina.net/OutOfMemory/blog/3131916git
最近有個項目須要對外提供一個接口,提供公網域名進行訪問,並且接口和交易訂單有關,因此安全性很重要;這裏整理了一下經常使用的一些安全措施以及具體如何去實現。
安全措施github
我的以爲安全措施大致來看主要在兩個方面,一方面就是如何保證數據在傳輸過程當中的安全性,另外一個方面是數據已經到達服務器端,服務器端如何識別數據,如何不被攻擊;下面具體看看都有哪些安全措施。面試
咱們知道數據在傳輸過程當中是很容易被抓包的,若是直接傳輸好比經過http協議,那麼用戶傳輸的數據能夠被任何人獲取;因此必須對數據加密,常見的作法對關鍵字段加密好比用戶密碼直接經過md5加密;如今主流的作法是使用https協議,在http和tcp之間添加一層加密層(SSL層),這一層負責數據的加密和解密;redis
如今主流的加密方式有對稱加密和非對稱加密:算法
對稱加密:對稱密鑰在加密和解密的過程當中使用的密鑰是相同的,常見的對稱加密算法有DES,AES;優勢是計算速度快,缺點是在數據傳送前,發送方和接收方必須商定好祕鑰,而後使雙方都能保存好祕鑰,若是一方的祕鑰被泄露,那麼加密信息也就不安全了;數據庫
非對稱加密:服務端會生成一對密鑰,私鑰存放在服務器端,公鑰能夠發佈給任何人使用;優勢就是比起對稱加密更加安全,可是加解密的速度比對稱加密慢太多了;普遍使用的是RSA算法;編程
兩種方式各有優缺點,而https的實現方式正好是結合了兩種加密方式,整合了雙方的優勢,在安全和性能方面都比較好;安全
對稱加密和非對稱加密代碼實現,jdk提供了相關的工具類能夠直接使用,此處不過多介紹;服務器
關於https如何配置使用相對來講複雜一些,能夠參考本人的以前的文章HTTPS分析與實戰
數據加簽就是由發送者產生一段沒法僞造的一段數字串,來保證數據在傳輸過程當中不被篡改;你可能會問數據若是已經經過https加密了,還有必要進行增強嗎?數據在傳輸過程當中通過加密,理論上就算被抓包,也沒法對數據進行篡改;可是咱們要知道加密的部分其實只是在外網,如今不少服務在內網中都須要通過不少服務跳轉,因此這裏的加簽能夠防止內網中數據被篡改;
數據簽名使用比較多的是md5算法,將須要提交的數據經過某種方式組合和一個字符串,而後經過md5生成一段加密字符串,這段加密字符串就是數據包的簽名,能夠看一個簡單的例子:
str:參數1={參數1}&參數2={參數2}&……&參數n={參數n}$key={用戶密鑰};
MD5.encrypt(str);
注意最後的用戶密鑰,客戶端和服務端都有一份,這樣會更加安全;
數據是很容易被抓包的,可是通過如上的加密,加簽處理,就算拿到數據也不能看到真實的數據;可是有不法者不關心真實的數據,而是直接拿到抓取的數據包進行惡意請求;這時候可使用時間戳機制,在每次請求中加入當前的時間,服務器端會拿到當前時間和消息中的時間相減,看看是否在一個固定的時間範圍內好比5分鐘內;這樣惡意請求的數據包是沒法更改裏面時間的,因此5分鐘後就視爲非法請求了;
解密後的數據,通過簽名認證後,咱們拿到數據包中的客戶端時間戳字段,而後用服務器當前時間去減客戶端時間,看結果是否在一個區間內,僞代碼以下:
long interval=5*60*1000;//超時時間 long clientTime=request.getparameter("clientTime"); long serverTime=System.currentTimeMillis(); if(serverTime-clientTime>interval){ return new Response("超過處理時長") }
大部分網站基本都須要用戶名和密碼才能登陸,並非誰來能使用個人網站,這其實也是一種安全機制;對應的對外提供的接口其實也須要這麼一種機制,並非誰均可以調用,須要使用接口的用戶須要在後臺開通appid,提供給用戶相關的密鑰;在調用的接口中須要提供appid+密鑰,服務器端會進行相關的驗證;
生成一個惟一的AppId便可,密鑰使用字母、數字等特殊字符隨機生成便可;生成惟一AppId根據實際狀況看是否須要全局惟一;可是不論是否全局惟一最好讓生成的Id有以下屬性:
趨勢遞增:這樣在保存數據庫的時候,使用索引性能更好;
信息安全:儘可能不要連續的,容易發現規律;
關於全局惟一Id生成的方式常見的有類snowflake方式等;
原本就是真實的用戶,而且開通了appid,可是出現頻繁調用接口的狀況;這種狀況須要給相關appid限流處理,經常使用的限流算法有令牌桶和漏桶算法;
經常使用的限流算法包括:令牌桶限流,漏桶限流,計數器限流**
1.令牌桶限流
令牌桶算法的原理是系統以必定速率向桶中放入令牌,填滿了就丟棄令牌;請求來時會先從桶中取出令牌,若是能取到令牌,則能夠繼續完成請求,不然等待或者拒絕服務;令牌桶容許必定程度突發流量,只要有令牌就能夠處理,支持一次拿多個令牌;
2.漏桶限流
漏桶算法的原理是按照固定常量速率流出請求,流入請求速率任意,當請求數超過桶的容量時,新的請求等待或者拒絕服務;能夠看出漏桶算法能夠強制限制數據的傳輸速度;
3.計數器限流
計數器是一種比較簡單粗暴的算法,主要用來限制總併發數,好比數據庫鏈接池、線程池、秒殺的併發數;計數器限流只要必定時間內的總請求數超過設定的閥值則進行限流;
具體基於以上算法如何實現,Guava提供了RateLimiter工具類基於基於令牌桶算法:
RateLimiter rateLimiter = RateLimiter.create(5);
以上代碼表示一秒鐘只容許處理五個併發請求,以上方式只能用在單應用的請求限流,不能進行全侷限流;這個時候就須要分佈式限流,能夠基於redis+lua來實現;
若是此appid進行過不少非法操做,或者說專門有一箇中黑系統,通過分析以後直接將此appid列入黑名單,全部請求直接返回錯誤碼;
如何爲何中黑咱們這邊不討論,咱們能夠給每一個用戶設置一個狀態好比包括:初始化狀態,正常狀態,中黑狀態,關閉狀態等等;或者咱們直接經過分佈式配置中心,直接保存黑名單列表,每次檢查是否在列表中便可;
這個能夠說是每一個系統都會有的處理機制,只有在數據是合法的狀況下才會進行數據處理;每一個系統都有本身的驗證規則,固然也可能有一些常規性的規則,好比身份證長度和組成,電話號碼長度和組成等等;
數據合法性校驗
合法性校驗包括:常規性校驗以及業務校驗
常規性校驗:包括簽名校驗,必填校驗,長度校驗,類型校驗,格式校驗等;
業務校驗:根據實際業務而定,好比訂單金額不能小於0等;
本文大體列舉了幾種常見的安全措施機制包括:數據加密、數據加簽、時間戳機制、AppId機制、限流機制、黑名單機制以及數據合法性校驗;固然確定有其餘方式,歡迎補充。
歡迎關注我的微信公衆號:Coder編程
歡迎關注Coder編程公衆號,主要分享數據結構與算法、Java相關知識體系、框架知識及原理、Spring全家桶、微服務項目實戰、DevOps實踐之路、每日一篇互聯網大廠面試或筆試題以及PMP項目管理知識等。更多精彩內容正在路上~
也分享一些雜文~
文章收錄至
Github: https://github.com/CoderMerlin/coder-programming
Gitee: https://gitee.com/573059382/coder-programming
歡迎關注並star~