API接口,類似http://mypay.com/refund/order_id=123&mch_id=123,這個(gè)請(qǐng)求我以商戶mch_id=123的身份給訂單號(hào)為order_id=123退款,如果服務(wù)器不辯別請(qǐng)求發(fā)起者的身份直接做相應(yīng)的操作,那是及其危險(xiǎn)的。
一般的,在PC端,我們是通過(guò)加密的cookie來(lái)做會(huì)員的辨識(shí)和維持會(huì)話的;但是cookie是屬于瀏覽器的本地存儲(chǔ)功能。APP端不能用,所以我們得通過(guò)token參數(shù)來(lái)辨識(shí)會(huì)員;而這個(gè)token該如何處理呢?
延伸開(kāi)來(lái),接口的安全性主要圍繞Token、Timestamp和Sign三個(gè)機(jī)制展開(kāi)設(shè)計(jì),保證接口的數(shù)據(jù)不會(huì)被篡改和重復(fù)調(diào)用。
一般來(lái)說(shuō),在前端對(duì)數(shù)據(jù)做加密或者前面,是不現(xiàn)實(shí)的。前后端使用HTTP協(xié)議進(jìn)行交互的時(shí)候,由于HTTP報(bào)文為明文,所以通常情況下對(duì)于比較敏感的信息可以通過(guò)在前端加密,然后在后端解密實(shí)現(xiàn)"混淆"的效果,避免在傳輸過(guò)程中敏感信息的泄露(如,密碼,證件信息等)。不過(guò)前端加密只能保證傳輸過(guò)程中信息是‘混淆’過(guò)的,對(duì)于高手來(lái)說(shuō),打個(gè)debugger,照樣可以獲取到數(shù)據(jù),并不安全,所謂的前端加密只是稍微增加了攻擊者的成本,并不能保證真正的安全。即使你說(shuō)在前端做了RSA公鑰加密,也很有可能被高手獲取到公鑰,并使用該公鑰加密數(shù)據(jù)后發(fā)給服務(wù)端,所以務(wù)必認(rèn)為前端的數(shù)據(jù)是不可靠的,服務(wù)端要加以辯別。敏感信息建議上https。
所以一般建議上https,敏感信息md5混淆,前端不傳輸金額字段,而是傳遞商品id,后端取商品id對(duì)應(yīng)的金額,將金額等參數(shù)加簽名發(fā)送到支付系統(tǒng)。金額可以是明文的。

一. Token
token授權(quán)機(jī)制:用戶使用用戶名密碼登錄后,后臺(tái)給客戶端返回一個(gè)token(通常是UUID),并將Token-UserId鍵值對(duì)存儲(chǔ)在redis中,以后客戶端每次請(qǐng)求帶上token,服務(wù)端獲取到對(duì)應(yīng)的UserId進(jìn)行操作。如果Token不存在,說(shuō)明請(qǐng)求無(wú)效。
弊端:token可以被抓包獲取,無(wú)法預(yù)防MITM中間人攻擊
二. Timestamp
用戶每次請(qǐng)求都帶上當(dāng)前時(shí)間的時(shí)間戳timestamp,服務(wù)器收到請(qǐng)求后對(duì)比時(shí)間差,超過(guò)一定時(shí)長(zhǎng)(如5分鐘),則認(rèn)為請(qǐng)求失效。時(shí)間戳超時(shí)機(jī)制是防御DOS攻擊的有效手段。
三. Sign和RSA算法
將token,timestamp等其他參數(shù)以字典序排序,再加上一個(gè)客戶端私密的唯一id(這種一般做在服務(wù)端,前端無(wú)法安全保存這個(gè)id)或使用私鑰簽名,將前面的字符串做MD5等加密,作為sign參數(shù)傳遞給服務(wù)端。
四. 公鑰加密,私鑰簽名
地球上最重要的加密算法:非對(duì)稱加密的RSA算法。公鑰加密的數(shù)據(jù),可以用私鑰解密;私鑰簽名(加密)的數(shù)據(jù),可以用公鑰驗(yàn)簽。
1977年,三位數(shù)學(xué)家Rivest、Shamir 和 Adleman 設(shè)計(jì)了一種算法,可以實(shí)現(xiàn)非對(duì)稱加密。這種算法用他們?nèi)齻€(gè)人的名字命名,叫RSA算法。
RSA原理是對(duì)極大整數(shù)做因數(shù)分解,以下摘自維基百科。


五. 微信支付的簽名方式
暫時(shí)比較忙沒(méi)時(shí)間,將于7月29日晚更新。
來(lái)更新啦。
微信支付安全規(guī)范,可以查看官方文檔https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=4_3
第1點(diǎn)中,其簽名算法最重要的一步,是在最后拼接了商戶私密的API密鑰,然后通過(guò)md5生成簽名,這時(shí)即使金額是明文也是安全的,如果有人獲取并修改了金額,但是簽名字段他是無(wú)法偽造的,因?yàn)樗麩o(wú)法知道商戶的API密鑰。當(dāng)然,除了微信支付的拼接API生成簽名的方法,我們也可以通過(guò)java自帶的security包進(jìn)行私鑰簽名。其中nonce隨機(jī)字符串,微信支付應(yīng)該做了校驗(yàn),可以防止重放攻擊,保證一次請(qǐng)求有效,如果nonce在微信支付那邊已經(jīng)存在,說(shuō)明該請(qǐng)求已執(zhí)行過(guò),拒絕執(zhí)行該請(qǐng)求。

參考資料
阮一峰老師的博客-RSA算法原理:http://www.ruanyifeng.com/blog/2013/07/rsa_algorithm_part_two.html
維基百科:https://zh.wikipedia.org/wiki/RSA%E5%8A%A0%E5%AF%86%E6%BC%94%E7%AE%97%E6%B3%95
喜歡我的文章的小伙伴歡迎關(guān)注我的公眾號(hào)“東瓜東瓜”哦,自己上微信搜一下。