簡易有效Api介面防攻擊策略

sakura_echo發表於2018-11-08

API安全

API(Application Programming Interface,應用程式程式設計介面)是一些預先定義的函式,目的是提供應用程式與開發人員基於某軟體或硬體得以訪問一組例程的能力,而又無需訪問原始碼,或理解內部工作機制的細節。

簡單的說,就是通過某一預先定義的渠道讀/寫資料的方式。

那麼Api的安全性就變得尤為重要,要明白使用、管理、協調和監控雲服務會在安全方面帶來什麼影響。安全性差的API會讓整個專案面臨涉及機密性、完整性、可用性和問責性的安全問題。

介面安全要求:

1.防偽裝攻擊(案例:在公共網路環境中,第三方 有意或惡意 的呼叫我們的介面)

2.防篡改攻擊(案例:在公共網路環境中,請求頭/查詢字串/內容 在傳輸過程被修改)

3.防重放攻擊(案例:在公共網路環境中,請求被截獲,稍後被重放或多次重放)

4.防資料資訊洩漏(案例:截獲使用者登入請求,截獲到賬號、密碼等)

設計原則:

**1.輕量級
2.適合於異構系統(跨作業系統、多語言簡易實現)
3.易於開發
4.易於測試
5.易於部署
6.滿足介面安全需求(滿足介面安全1,2,3),無過度設計。**

適用範圍:

**1.所有寫操作介面(增、刪、改 操作)
2.非公開的讀介面(如:涉密/敏感/隱私 等資訊)**

介面引數簽名 實現思路參考:

必要的介面傳遞引數:

引數名 型別 必選 描述
Key=Value String 介面引數正常使用
sign String 該次介面呼叫的簽名值,伺服器端防止偽裝請求,防篡改,防重發識別的重要

簽名演算法過程:

假設當前與伺服器約定的appkey=123456;

1.對除簽名外的所有請求引數按key=value做升序排列
則:有c=3,b=2,a=1 三個引數,另加上appkey後, 按key排序後為:a=1,b=2,c=3;
2. 把引數名和引數值連線成字串,最後拼接appkey,得到拼裝字元:a=1&b=2&c=3&123456
3.然後進行32位MD5加密,最後將到得MD5加密摘要轉化成大寫。擷取密文前18位作為pwd的引數進行傳遞。


工具類:

Map物件排序:

  /**
     * 方法用途: 對所有傳入引數按照欄位名的Unicode碼從小到大排序(字典序),並且生成url引數串
     *
     * @param paraMap    要排序的Map物件
     * @param urlEncode  是否需要URLENCODE
     * @param keyToLower 是否需要將Key轉換為全小寫
     *                   true:key轉化成小寫,false:不轉化
     * @return
     */
    public static String formatUrlMap(Map<String, String> paraMap, boolean urlEncode, boolean keyToLower) {
        String buff = "";
        Map<String, String> tmpMap = paraMap;
        try {
            List<Map.Entry<String, String>> infoIds = new ArrayList<Map.Entry<String, String>>(tmpMap.entrySet());
            // 對所有傳入引數按照欄位名的 ASCII 碼從小到大排序(字典序)
            Collections.sort(infoIds, new Comparator<Map.Entry<String, String>>() {
                @Override
                public int compare(Map.Entry<String, String> o1, Map.Entry<String, String> o2) {
                    return (o1.getKey()).toString().compareTo(o2.getKey());
                }
            });
            // 構造URL 鍵值對的格式
            StringBuilder buf = new StringBuilder();
            for (Map.Entry<String, String> item : infoIds) {
                if (!TextUtils.isEmpty(item.getKey())) {
                    String key = item.getKey();
                    String val = item.getValue();
                    if (urlEncode) {
                        val = URLEncoder.encode(val, "utf-8");
                    }
                    if (keyToLower) {
                        buf.append(key.toLowerCase() + "=" + val);
                    } else {
                        buf.append(key + "=" + val);
                    }
                    buf.append("&");
                }

            }
            buff = buf.toString();
            if (buff.isEmpty() == false) {
                buff = buff.substring(0, buff.length() - 1);
            }
        } catch (Exception e) {
            return null;
        }
        return buff;
    }

字串MD5:

 public static String md5(String string) {
        if (TextUtils.isEmpty(string)) {
            return "";
        }
        MessageDigest md5 = null;
        try {
            md5 = MessageDigest.getInstance("MD5");
            byte[] bytes = md5.digest(string.getBytes());
            String result = "";
            for (byte b : bytes) {
                String temp = Integer.toHexString(b & 0xff);
                if (temp.length() == 1) {
                    temp = "0" + temp;
                }
                result += temp;
            }
            return result;
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return "";
    }

其他常見的加密方式:

DES加密演算法:DES加密演算法是一種分組密碼,以64位為分組對資料加密,它的金鑰長度是56位,加密解密用同一演算法。DES加密演算法是對金鑰進行保密,而公開演算法,包括加密和解密演算法。這樣,只有掌握了和傳送方相同金鑰的人才能解讀由DES加密演算法加密的密文資料。因此,破譯DES加密演算法實際上就是搜尋金鑰的編碼。對於56位長度的金鑰來說,如果用窮舉法來進行搜尋的話,其運算次數為256。

隨著計算機系統能力的不斷髮展,DES的安全性比它剛出現時會弱得多,然而從非關鍵性質的實際出發,仍可以認為它是足夠的。不過,DES現在僅用於舊系統的鑑定,而更多地選擇新的加密標準。

AES加密演算法:AES加密演算法是密碼學中的高階加密標準,該加密演算法採用對稱分組密碼體制,金鑰長度的最少支援為128、192、256,分組長度128位,演算法應易於各種硬體和軟體實現。這種加密演算法是美國聯邦政府採用的區塊加密標準,這個標準用來替代原先的DES,已經被多方分析且廣為全世界所使用。

AES加密演算法被設計為支援128/192/256位(/32=nb)資料塊大小(即分組長度);支援128/192/256位(/32=nk)密碼長度,,在10進位制裡,對應34×1038、62×1057、1.1×1077個金鑰。

RSA加密演算法:RSA加密演算法是目前最有影響力的公鑰加密演算法,並且被普遍認為是目前最優秀的公鑰方案之一。RSA是第一個能同時用於加密和數宇簽名的演算法,它能夠抵抗到目前為止已知的所有密碼攻擊,已被ISO推薦為公鑰資料加密標準。RSA加密演算法基於一個十分簡單的數論事實:將兩個大素數相乘十分容易,但那時想要,但那時想要對其乘積進行因式分解卻極其困難,因此可以將乘積公開作為加密金鑰。

Base64加密演算法:Base64加密演算法是網路上最常見的用於傳輸8bit位元組程式碼的編碼方式之一,Base64編碼可用於在HTTP環境下傳遞較長的標識資訊。例如,在JAVAPERSISTENCE系統HIBEMATE中,採用了Base64來將一個較長的唯一識別符號編碼為一個字串,用作HTTP表單和HTTPGETURL中的引數。在其他應用程式中,也常常需要把二進位制資料編碼為適合放在URL(包括隱藏表單域)中的形式。此時,採用Base64編碼不僅比較簡短,同時也具有不可讀性,即所編碼的資料不會被人用肉眼所直接看到。

MD5加密演算法:MD5為電腦保安領域廣泛使用的一種雜湊函式,用以提供訊息的完整性保護。對MD5加密演算法簡要的敘述可以為:MD5以512位分組來處理輸入的資訊,且每一分組又被劃分為16個32位子分組,經過了一系列的處理後,演算法的輸出由四個32位分組組成,將這四個32位分組級聯後將生成—個128位雜湊值。

MD5被廣泛用於各種軟體的密碼認證和鑰匙識別上。MD5用的是雜湊函式,它的典型應用是對一段資訊產生資訊摘要,以防止被篡改。MD5的典型應用是對一段Message產生fingerprin指紋,以防止被“篡改”。如果再有—個第三方的認證機構,用MD5還可以防止檔案作者的“抵賴”,這就是所謂的數字簽名應用。MD5還廣泛用於作業系統的登陸認證上,如UNIX、各類BSD系統登入密碼、數字簽名等諸多方


相關文章