Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android—構建安全的Android客戶端請求,避免非法請求

Android—構建安全的Android客戶端請求,避免非法請求

編輯:關於Android編程

今天通過實例來介紹一下如何構建安全的Android客戶端請求,避免非法請求:

服務器端代碼:

代碼1—工具類:

package com.ghj.packageoftool;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * 字符串SHA-1轉換
 * 
 * @author 高煥傑
 */
public class Sha1Util {

	public static String SHA(String paramString) {
		MessageDigest localMessageDigest;
		try {
			localMessageDigest = MessageDigest.getInstance("SHA-1");
			localMessageDigest.update(paramString.getBytes());
			return toHexString(localMessageDigest.digest()).toUpperCase();
		} catch (NoSuchAlgorithmException localNoSuchAlgorithmException) {
			localNoSuchAlgorithmException.printStackTrace();
			return "";
		}
	}

	private static String toHexString(byte[] digestArray) {
		if (digestArray == null || digestArray.length <= 0) {
			return "";
		}
		StringBuilder stringBuilder = new StringBuilder();
		for (int i = 0; i < digestArray.length; i++) {
			String hexString = Integer.toHexString(digestArray[i] & 0xFF);
			if (hexString.length() < 2) {
				stringBuilder.append(0);
			}
			stringBuilder.append(hexString);
		}
		return stringBuilder.toString();
	}

	public static void main(String[] paramArrayOfString) {
		SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String timeStamp = dateFormat.format(new Date());
		String str = SHA("2014-12-16 10:19:30" + "miyue");
		System.out.println(timeStamp + "signature:"+str.equals("927CFBFC8D0F049CEDB83FB10FBEC9AC784A9460"));
	}	
}

代碼2—過濾器類:

package com.ghj.packageoffilter;

import java.io.IOException;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.Date;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.ghj.packageoftool.Sha1Util;

/**
 * 本過濾器用來校驗請求是否合法
 * 
 * @author 高煥傑
 */
public class CheckRequestFilter implements Filter {

	public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
		HttpServletRequest request = (HttpServletRequest) req;
		HttpServletResponse response = (HttpServletResponse) res;
		String secretKey = "AndroidClient";
		String timeStamp = request.getParameter("timeStamp");
		String signature = request.getParameter("signature");
		String dateDifference = getDateDifference(timeStamp);

		if(dateDifference == null){//系統時間和時間戳的差值為null,這說明該請求中的時間被認為的進行了修改且時間格式不正確。
			sendErrorState(response, 0);
		}
		if(!Sha1Util.SHA(timeStamp + secretKey).equals(signature)){//如果時間戳被人為地進行了修改造成請求簽名不一致。
			sendErrorState(response, 1);
		}else if(Integer.parseInt(dateDifference) > 1000*60*5){//如果請求從創建到到達服務器端的時間大於5分鐘,則認為請求超時——不給別有用心的人思考的時間
			sendErrorState(response, 2);
		}else{
			chain.doFilter(request, response);
		}
	}

	private void sendErrorState(HttpServletResponse response, int errorState) {
		PrintWriter out = null;
		try {
			out = response.getWriter();
			out.println("errorState:" + errorState);
			out.flush();
		} catch (IOException e) {
			e.printStackTrace();
		}finally{
			out.close();
		}
		return;
	}
	
	/**
	 * @see: 獲取時間戳與當前系統時間的差值(以毫秒為單位)
	 * 
	 * @author GaoHuanjie
	 */
	private String getDateDifference(String timeStamp){
		try{ 
			if(timeStamp != null){
				return String.valueOf(new Date().getTime()- new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(timeStamp).getTime());//獲取系統時間(毫秒)-時間戳時間(毫秒)
			}
		}catch(Exception e){
			e.printStackTrace();
		}
		return null;
	}


	public void destroy() {

	}

	public void init(FilterConfig filterConfig) throws ServletException {

	}
}

代碼3—Servlet類:

package com.ghj.packageofservlet;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class ServerServlet extends HttpServlet {

	private static final long serialVersionUID = -1052048925901833921L;

	public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
		doPost(request, response);
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		response.setContentType("text/plain; charset=UTF-8");
		request.setCharacterEncoding("UTF-8");
		System.err.println(request.getParameter("clientData"));
		PrintWriter printWriter = response.getWriter();
		printWriter.print("您好Android客戶端!");
		printWriter.flush();
		printWriter.close();
	}
}

代碼4—配置文件:




	
		checkRequestFilter
		com.ghj.packageoffilter.CheckRequestFilter
	

	
		checkRequestFilter
		*.do
	
	
	
		ServerServlet
		com.ghj.packageofservlet.ServerServlet
	

	
		ServerServlet
		/ServerServlet.do
	

客戶端代碼:

代碼1—工具類:

與服務器端工具類完全一樣!

代碼1—Activity類:

package com.ghj.packageofactivity;

import java.text.SimpleDateFormat;
import java.util.Date;

import org.apache.http.Header;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;

import com.example.androidclient.R;
import com.ghj.packageoftool.Sha1Util;
import com.loopj.android.http.AsyncHttpClient;
import com.loopj.android.http.AsyncHttpResponseHandler;
import com.loopj.android.http.RequestParams;

public class AndroidClientActivity extends Activity {
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.android_client);

		Button sendInfoButton = (Button) findViewById(R.id.sendInfoButton);
		sendInfoButton.setOnClickListener(new OnClickListener(){
			@Override
			@SuppressLint("SimpleDateFormat")
			public void onClick(View v) {
				String secretKey = "AndroidClient";
				String timeStamp = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
				RequestParams requestParams = new RequestParams();
				requestParams.add("clientData", "您好服務器端!");
				requestParams.add("timeStamp", timeStamp);
				requestParams.add("signature", Sha1Util.SHA(timeStamp + secretKey));
				new AsyncHttpClient().post("http://172.16.99.207:8080/CheckRequest/ServerServlet.do", requestParams, new AsyncHttpResponseHandler() {
					@Override
					public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) {
						if(statusCode == 200){
							String responseData = new String(responseBody);
							if(responseData.contains("errorState")){
								Toast.makeText(AndroidClientActivity.this, "請求非法!", Toast.LENGTH_LONG).show();
							}else{
								Toast.makeText(AndroidClientActivity.this, new String(responseBody), Toast.LENGTH_LONG).show();
							}
						}
					}
					@Override
					public void onFailure(int statusCode, Header[] headers, byte[] responseBody, Throwable error) {
						Toast.makeText(AndroidClientActivity.this, "沒有獲取到Android服務器端的響應!", Toast.LENGTH_LONG).show();
					}
				});
			}
		});
	}
}

總結:

1、由於該Demo客戶端需要依賴很多文件和一些jar包,所以建議直接下載完整Demo工程——【0分下載Demo

2、實現這個功能其實很簡單:一句話,想盡一切方法讓別有用心的人發出的請求失效!!!

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved