加密算法中的加鹽值

在應用中,出於到安全的考慮和數據的保密,需要使用到加密算法,有時候爲了讓加密的的結果更加撲朔迷離神鬼莫測一些,常常會給被加密的數據加點“鹽”。說白了,鹽就是一串數字,完全是自己定義的,不多說,上實例。

    /**
     * 獲取當前用戶鹽
     *
     * @param string $extraKey 額外密鑰
     * @return string
     */
    public function getSalt($extraKey = null)
    {
        // 今天凌晨5點以後~第二天凌晨5點前
        if (date('G') >= 5) {
            $dateString = date('md');
        }
        // 今天凌晨5點前
        // 日期標示符仍用昨天的
        else {
            $dateString = date('md', strtotime('-1 day'));
        }

        return md5('VoyageMobile:' . $dateString . ':' . $this->_uid . ':' . $extraKey);
    }

這就是我們程序中,使用的一個生成鹽值的函數,這函數的返回值就是所謂的鹽值,請注意這個函數的命名,哈哈。 函數的使用如下:

    /**
     * 加密
     *
     * @param string $content 待加密內容
     * @param string $extraKey 額外密鑰
     * @return string
     */
    public function encrypt($content, $extraKey = null)
    {
        return Helper_Cryption_Rijndael::encrypt($content, $this->getSalt($extraKey));
    }

爲什麼我們要使用鹽值。在回答這個問題之前,我們討論一下加密算法,常用的加密算法大致分爲兩種:可逆和不可逆,如MD5()不可逆。RijnDael可逆。

在不可逆的加密算法中,加鹽值通常是“錦上添花”,因爲類似於Md5()這樣的算法已經夠用了,如果還擔心的會被暴力破解的話,可加點鹽。 如:

md5('VoyageMobile:' . $this->getSalt($extraKey));
重點是在可逆的算法中使用加鹽值。

在我們的遊戲中,我們需要對用戶ID即UID使用可逆算法加密,爲什麼呢,如果不加密會很危險,例如,其它玩家獲取到你的UID可以重複攻擊你,或者改一下UID就可以攻擊其他玩家,在造船廠,改一下船的ID,如果後臺不驗證,就可以隨意造船了,這就是串號攻擊。還有一個特殊的情況,如果我知道了一個裝備的ID,如果這個裝備恰好是贈品,不能在商店出售,我可以僞造一個URL請求購買,這個時候,後臺判斷這個商品確實存在(因爲它是贈品),所以可能購買成功。

這個時候就要對ID加密了,而且還是可逆的,因爲我需要知道你將要攻擊誰,購買什麼裝備,對吧。這個時候或許加鹽的必要性還是沒有體現出來,因爲我對ID加密就比較安全了,這樣就可以防止串號了,何必還有一個加鹽值。

請注意,會有這樣的情況,在活動模塊中,我得到一個裝備,我雖然不知道itemId,當是我知道了這個裝備ID加密後的一串數字。然後我就去拿這個數字去商店裏面購買這個裝備,而這個裝備又是不能購買的。在數據庫中,我們把不能購買的裝備的價格設置爲0,並且和能購買的裝備放在一個表中。 注意,這樣的設計導致我能夠購買到這個裝備,而且一毛錢不花!

怎樣解決這個問題,我們就需要加鹽了。思路就是,在活動模塊中,給所有的裝備加密使用鹽值,在商店模塊中,也給所有的裝備加鹽,使用不同的鹽值。這樣的結果就是同一個裝備,在不同的模塊itemId也是不同的。

在後臺也需要加一個判斷,這個裝備是否能購買!

這就是加鹽的一個好處。

需要注意點:

保證鹽值的唯一行,在我們遊戲中,通常會使用到玩家UID造鹽,這樣,不同的玩家看到的加密後的字符串也不一樣。

保證鹽值的時效性,這也是出於安全的考慮,經常換鹽值,這樣加密後的字符串也是變動的,不容易找到規律。



發佈了41 篇原創文章 · 獲贊 14 · 訪問量 14萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章