1. 程式人生 > >充值系列——充值系統安全問題(四)

充值系列——充值系統安全問題(四)

這是充值系列的最後一篇,將討論充值安全的問題。正如這個系列的其他文章提到的,充值系統的流程如下:

注意: 4,5執行順序不確定,步驟4是支付平臺自動向伺服器請求,步驟5是玩家點選“返回商家網站”時支付平臺請求伺服器,如果玩家不點選,這可能不會觸發,所以這是一個不可靠的請求。

支付的安全問題主要發生在步驟3和4中。下面是詳細說明:

在步驟3中,客戶端需要把訂單資訊提交給支付平臺,比如玩家購買100個金幣,他需要支付人民幣10元。訂單資訊如下:

{
 "product_name" : 100金幣,
 "total_fee" 100, 
 "currency": RMB
}

當玩家點選提交訂單的時候,會把這個訂單資訊提交到支付平臺,如果有人劫持這個請求,並且把訂單資訊的總費用修改為0.1元,那麼支付平臺只會扣除玩家0.1元,同時,這筆訂單會順利完成。也就是玩家只花了0.1元購買了原來100元的商品。

在步驟4中,支付平臺會把訂單處理結果和訂單資訊返回給伺服器,例如返回的結果如下:

{
 "status" : "fail"  // 表示支付失敗
 "product_name" : 100金幣,
 "total_fee" 100, 
 "currency": RMB
}

這裡,如果某個玩家把這個URL劫持,並且修改其中的某些資訊,例如把支付失敗改為支付成功,或者自己拼接一個URL向遊戲伺服器發起請求,那後果可想而知。我們需要保證訂單除了結果沒有被修改,同時還要保證這個請求來自於支付寶。

針對串改訂單資訊的問題,支付寶的做法是使用RSA演算法加密訂單資訊,對於步驟4中發生的問題,支付寶要求伺服器驗證請求是否來自於支付寶,同時驗證返回的訂單資訊,如訂單資訊是否被串改,支付狀態是否為成功等。

RSA加密的思路: 把訂單資訊和商戶私鑰加密。同時把這個簽名傳給支付寶。只要不洩露商戶私鑰,訂單資訊基本上不可能會被串改。當然,伺服器也會驗證訂單資訊沒有被修改。

伺服器端驗證訂單資訊是否被修改:

第一步:伺服器端會接收到從支付寶返回過來的訂單資訊和之前簽名的結果,這個時候,伺服器在把訂單資訊簽名,同時和之前的簽名結果對比,如果一致,說明訂單資訊沒有被修改。

第二步:獲取支付寶返回的資料之一notify_id,按照支付寶要求的格式拼接成URL,提交給支付寶,如果返回為true,則說明這請求確實來自於支付寶。如果所示:

做支付系統的一些思考:

1:在做遊戲後臺的時候,需要經常向遊戲伺服器請求資料,這裡就有一個安全問題,遊戲伺服器如何信任這個請求呢,這裡就可以參考支付寶的簽名機制:把需要向遊戲伺服器請求的資料和一個”密文“生成一個簽名,把這個簽名也提交給遊戲伺服器,當遊戲伺服器接受到請求後,再把請求的資料和”密文“加密,同時把結果和接受到的簽名比對,這樣就可以判斷這個URL的合法性了。

2:支付平臺接入都大同小異,關鍵是要理解支付的流程,更深入支付流程的規範性和安全性,這對以後的程式設計也很有幫助。

3:在接入360,91這樣的平臺的時候,需要理解oauth2.0,也涉及到URL請求合法性的問題,但是Oauth2.0和本篇文章的做法不同。下一篇文章,將討論一下oauth2.0的應用。

充值系列—充值系統資料庫設計(一)

充值系列——充值系統的架構(二)

充值系列——充值系統業務邏輯層實現(三)