一、爲什麼需要認證
經由HTTP協議進行通信的數據大多都是未經過加密的明文,包括請求參數、返回值、cookie、head等數據,因此,外界通過對通信的監聽,便可以輕而易舉地根據請求和響應雙方的格式,僞造、修改、竊取信息。而且相對TCP來說,HTTP的通信更易於攻擊。
所以,爲了防止在通信的過程中,數據被中途攔截和修改;或者虛假的客戶端冒充正常的客戶端發起請求,非法獲取數據;再或者是客戶端與虛假的服務端進行通信,將個人信息泄露給惡意的攻擊者,需要對請求和響應的參數及客戶端的身份進行認證,以保住正確信息發送給了合法的接收者。
二、原理
對於普通的非敏感數據,我們更多關注其真實性和準確性。因此,如何在通信過程中保障數據不被篡改,纔是考慮的首要問題。
常見的摘要算法包括:MD5、SHA等。用戶先發出一個沒有認證證書的請求,Web服務器回覆一個帶有WWW-authenticate頭的響應,指明訪問所請求的資源需要證書。但是和基礎認證發送以Base64編碼的用戶名和密碼不同,在摘要認證中服務器讓客戶選一個隨機數(稱作”nonce“),然後瀏覽器使用一個單向的加密函數生成一個消息摘要(messagedigest),該摘要是關於用戶名、密碼、給定的nonce值、HTTP方法,以及所請求的URL。消息摘要函數也被成爲散列算法,是一種在一個方向上很容易計算,反方向卻不可行的加密算法。與基礎認證對比,解碼基礎認證中的Base64是很容易辦到的。在服務器口令中,可以指定任意的散列算法。
三、實現
HttpURLConnection hc = null;
try
{
hc = (HttpURLConnection) new URL(url).openConnection();
hc.setConnectTimeout(10000);
hc.setReadTimeout(10000);
hc.setDoInput(true);
hc.setDoOutput(true);
hc.setUseCaches(false);
String content = param;
DataOutputStream out = new DataOutputStream(hc.getOutputStream());
out.writeBytes(content);
out.flush();
out.close();
//從hc中取出sessionId
for (int i = 1; (key = hc.getHeaderFieldKey(i)) != null; i++)
{
if (key.equalsIgnoreCase("Set-Cookie"))
{
sessionId = hc.getHeaderField(key);
sessionId = sessionId.substring(0, sessionId.indexOf(";"));
break;
}
}
BufferedReader reader = new BufferedReader(
new InputStreamReader(hc.getInputStream()));
String lines;
while ((lines = reader.readLine()) != null)
{
break;
}
reader.close();
catch (Exception e)
{
//
//e.printStackTrace();
return false;
}
finally
{
// 斷開連接
hc.disconnect();
}