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>>() {@Overridepublic 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系統登錄密碼、數字簽名等諸多方