zoukankan      html  css  js  c++  java
  • Android—构建安全的Androidclient请求,避免非法请求

            今天通过实例来介绍一下怎样构建安全的Android客户端请求。避免非法请求:

            server端代码:

            代码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){//假设请求从创建到到达server端的时间大于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—配置文件:

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
    	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
    	http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
    
    	<filter>
    		<filter-name>checkRequestFilter</filter-name>
    		<filter-class>com.ghj.packageoffilter.CheckRequestFilter</filter-class>
    	</filter>
    
    	<filter-mapping>
    		<filter-name>checkRequestFilter</filter-name>
    		<url-pattern>*.do</url-pattern>
    	</filter-mapping>
    	
    	<servlet>
    		<servlet-name>ServerServlet</servlet-name>
    		<servlet-class>com.ghj.packageofservlet.ServerServlet</servlet-class>
    	</servlet>
    
    	<servlet-mapping>
    		<servlet-name>ServerServlet</servlet-name>
    		<url-pattern>/ServerServlet.do</url-pattern>
    	</servlet-mapping>
    </web-app>

            客户端代码:

            代码1—工具类:

             与server端工具类全然一样!

            代码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", "您好server端!");
    				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, "没有获取到Androidserver端的响应!

    ", Toast.LENGTH_LONG).show(); } }); } }); } }

            总结:

            1、因为该Demo客户端须要依赖非常多文件和一些jar包,所以建议直接下载完整Demoproject——0分下载Demo

               2、实现这个功能事实上非常easy:一句话,想尽一切方法让别实用心的人发出的请求失效!

    !!

  • 相关阅读:
    Centos 安装Apache软件
    简单工厂模式和策略模式的差别
    ASCII对比表
    谋哥:这个时代没有比程序猿更适合创业
    Android 自己主动化測试(3)&lt;monkeyrunner&gt; 依据ID查找对象&amp;touch&amp;type (python)
    Java学习笔记七(目录操作)
    我读经典(7):读《程序猿生存定律》有感
    SELECT语句逻辑运行顺序,你知道吗?
    Qt Creator新安装后运行一个程序后,出现错误:Error while building/deploying project dict-qt (kit: Desktop Qt 5.10.0 MinGW 32bit) When executing step "qmake"
    软件的各版本分类介绍
  • 原文地址:https://www.cnblogs.com/yjbjingcha/p/8384213.html
Copyright © 2011-2022 走看看