使用3DES加密与解密实习Android端和后台的数据加密传输

2022-11-30 10:08:30 浏览数 (1)

这篇主要讲怎么进行加密的安全传输。通过双发所持有的秘钥进行解密,具有很高的安全性。

下面就不多说啦直接看代码。

Android端:

ThreeDesUtil加密解密类:

代码语言:javascript复制
package com.ge.tool;
import java.security.Key;
import javax.crypto.Cipher;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

import Decoder.BASE64Decoder;
import Decoder.BASE64Encoder;
/**
 * 使用3DES加密与解密,可对byte[],String类型进行加密与解密 密文可使用String,byte[]存储.
 * @author 陈嘉瑛
 * @version 2015-04-11
 */
public class ThreeDesUtil {
    private String strKey;        //密钥
    private final String TRANSFORMATION = "DES/CBC/PKCS5Padding";
    private final byte[] iv = {1,2,3,4,5,6,7,8};

    /**
     * 根据参数生成KEY
     * 作者:陈嘉瑛
     * 时间:2015-04-11
     * @param strKey 密钥字符串
     */
    public void getKey(String strKey) {
    	this.strKey = strKey;
    }

    /**
     * 加密String明文输入,String密文输出
     * 作者:陈嘉瑛
     * 时间:2015-04-11
     * @param strMing String明文
     * @return String密文
     */
    public String getEncString(String strMing) {
        byte[] byteMi = null;
        byte[] byteMing = null;
        String strMi = "";
        BASE64Encoder base64en = new BASE64Encoder();
        try {
            byteMing = strMing.getBytes("UTF8");
            byteMi = this.getEncCode(byteMing);
            strMi = base64en.encode(byteMi);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            base64en = null;
            byteMing = null;
            byteMi = null;
        }
        return strMi;
    }

    /**
     * 解密 以String密文输入,String明文输出
     * 作者:陈嘉瑛
     * 时间:2015-04-11
     * @param strMi String密文
     * @return String明文
     */
    public String getDesString(String strMi) {
        BASE64Decoder base64De = new BASE64Decoder();
        byte[] byteMing = null;
        byte[] byteMi = null;
        String strMing = "";
        try {
            byteMi = base64De.decodeBuffer(strMi);
            byteMing = this.getDesCode(byteMi);
            strMing = new String(byteMing, "UTF8");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            base64De = null;
            byteMing = null;
            byteMi = null;
        }
        return strMing;
    }

    /**
     * 加密以byte[]明文输入,byte[]密文输出
     * 作者:陈嘉瑛
     * 时间:2015-04-11
     * @param byteS byte[]明文
     * @return byte[]密文
     */
    private byte[] getEncCode(byte[] byteS) {
        byte[] byteFina = null;
        Cipher cipher;
        try {
        	DESKeySpec dks = new DESKeySpec(strKey.getBytes());
            Key secretKey = SecretKeyFactory.getInstance("DES").generateSecret(dks);
            IvParameterSpec paramSpec = new IvParameterSpec(iv);
            cipher = Cipher.getInstance(TRANSFORMATION);
            cipher.init(Cipher.ENCRYPT_MODE, secretKey, paramSpec);
            byteFina = cipher.doFinal(byteS);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            cipher = null;
        }
        return byteFina;
    }

    /**
     * 解密以byte[]密文输入,以byte[]明文输出
     * 作者:陈嘉瑛
     * 时间:2015-04-11
     * @param byteD byte[]密文
     * @return byte[]明文
     */
    private byte[] getDesCode(byte[] byteD) {
        Cipher cipher;
        byte[] byteFina = null;
        try {
        	IvParameterSpec zeroIv = new IvParameterSpec(iv);
        	SecretKeySpec key = new SecretKeySpec(strKey.getBytes(), "DES");
        	cipher = Cipher.getInstance(TRANSFORMATION);
        	cipher.init(Cipher.DECRYPT_MODE, key, zeroIv);
            byteFina = cipher.doFinal(byteD);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            cipher = null;
        }
        return byteFina;
    }
}

activity中的代码

代码语言:javascript复制
package com.example.test.aquery_test_2;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import com.androidquery.AQuery;
import com.androidquery.callback.AjaxCallback;
import com.androidquery.callback.AjaxStatus;
import com.example.test.aquery_test_2.entity.JsonEntity;
import com.example.test.aquery_test_2.entity.User;
import com.example.test.aquery_test_2.tool.DESUtils;
import com.example.test.aquery_test_2.tool.ThreeDesUtil;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class MainActivity extends Activity {
    private Button button,button2;
    private EditText edittext,edittext2;
    private String str2="";
    private String name,pwd;
    private static String cryptKey = "12345678";
    private AQuery mAQuery;//Android Query简化了附加事件处理程序的过程。
    // 它不会构建出接口或者匿名类,我们只需要确保它们不会把事件处理程序的方法名拼写错。
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        button=(Button)findViewById(R.id.button);//确定按钮
        button2=(Button)findViewById(R.id.button2);//取消按钮
        edittext=(EditText)findViewById(R.id.editText);//账号输入框
        edittext2=(EditText)findViewById(R.id.editText2);//密码输入框
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String url = "http://192.168.42.110:8080/YX_2015_9_9_SSH_Test_1/login.action";//Java后台的URL
                List<User> list=new ArrayList<User>();
                User user=new User(edittext.getText().toString().trim(),edittext2.getText().toString().trim());
                list.add(user);
                Map<String, String> params = new HashMap<String, String>();
                JsonEntity jsonEntity=new JsonEntity(list);
                String jsonStr=jsonEntity.createJSONObject();
                final ThreeDesUtil des = new ThreeDesUtil();
                //生成密钥
                des.getKey(cryptKey);
                String content = des.getEncString(jsonStr);
                Log.w("System.out","加密前的jsonStr=" jsonStr);
                Log.w("System.out","加密后的content=" content);
                params.put("json",content);
                //利用AQuery中的ajax实现异步加载的功能,其中URL为访问路劲,params为传入的数据,String.class为返回数据的格式
                final AQuery aq=new AQuery(MainActivity.this);
                aq.ajax(url,params,String.class, new AjaxCallback<String>() {
                    @Override
                    public void callback(String url, String json, AjaxStatus status) {
                        if(json != null){
                            //successful ajax call, show status code and json content
                            Log.w("System.out","加密前的json=" json.toString());
                            try {
                                json=des.getDesString(json);
                                Log.w("System.out", "加密后的json="   json.toString());
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                            Toast.makeText(aq.getContext(), status.getCode()   ":"   json.toString(), Toast.LENGTH_LONG).show();
                        }else{
                            //ajax error, show error code
                            Toast.makeText(aq.getContext(), "Error:"   status.getCode(), Toast.LENGTH_LONG).show();
                        }
                    }
                });
            }
        });
    }
}

Android中有两个输入框,一个是username账号输入,另一个是password密码输入。

输入为:username=112 password=231

运行结果为:

代码语言:javascript复制
加密前的jsonStr=[{"password":"231","username":"112"}]
加密后的content=XWB/lOUWrDHUoXb5HSxVzO/XZLoFpCl81Zb4TgaJ8GCayYCtjMioqA==
加密前的json=BJXFJDxlk5kPdL1LHknQFPBrV6thmGjV
加密后的json=添加成功!!!

服务端的代码:

在写代码之前要先导入BASE64Encoder.jar包。

ThreeDesUtil加密解密类:

代码语言:javascript复制
package com.ge.tool;
import java.security.Key;
import javax.crypto.Cipher;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

import Decoder.BASE64Decoder;
import Decoder.BASE64Encoder;
/**
 * 使用3DES加密与解密,可对byte[],String类型进行加密与解密 密文可使用String,byte[]存储.
 * @author 陈嘉瑛
 * @version 2015-04-11
 */
public class ThreeDesUtil {
    private String strKey;        //密钥
    private final String TRANSFORMATION = "DES/CBC/PKCS5Padding";
    private final byte[] iv = {1,2,3,4,5,6,7,8};

    /**
     * 根据参数生成KEY
     * 作者:陈嘉瑛
     * 时间:2015-04-11
     * @param strKey 密钥字符串
     */
    public void getKey(String strKey) {
    	this.strKey = strKey;
    }

    /**
     * 加密String明文输入,String密文输出
     * 作者:陈嘉瑛
     * 时间:2015-04-11
     * @param strMing String明文
     * @return String密文
     */
    public String getEncString(String strMing) {
        byte[] byteMi = null;
        byte[] byteMing = null;
        String strMi = "";
        BASE64Encoder base64en = new BASE64Encoder();
        try {
            byteMing = strMing.getBytes("UTF8");
            byteMi = this.getEncCode(byteMing);
            strMi = base64en.encode(byteMi);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            base64en = null;
            byteMing = null;
            byteMi = null;
        }
        return strMi;
    }

    /**
     * 解密 以String密文输入,String明文输出
     * 作者:陈嘉瑛
     * 时间:2015-04-11
     * @param strMi String密文
     * @return String明文
     */
    public String getDesString(String strMi) {
        BASE64Decoder base64De = new BASE64Decoder();
        byte[] byteMing = null;
        byte[] byteMi = null;
        String strMing = "";
        try {
            byteMi = base64De.decodeBuffer(strMi);
            byteMing = this.getDesCode(byteMi);
            strMing = new String(byteMing, "UTF8");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            base64De = null;
            byteMing = null;
            byteMi = null;
        }
        return strMing;
    }

    /**
     * 加密以byte[]明文输入,byte[]密文输出
     * 作者:陈嘉瑛
     * 时间:2015-04-11
     * @param byteS byte[]明文
     * @return byte[]密文
     */
    private byte[] getEncCode(byte[] byteS) {
        byte[] byteFina = null;
        Cipher cipher;
        try {
        	DESKeySpec dks = new DESKeySpec(strKey.getBytes());
            Key secretKey = SecretKeyFactory.getInstance("DES").generateSecret(dks);
            IvParameterSpec paramSpec = new IvParameterSpec(iv);
            cipher = Cipher.getInstance(TRANSFORMATION);
            cipher.init(Cipher.ENCRYPT_MODE, secretKey, paramSpec);
            byteFina = cipher.doFinal(byteS);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            cipher = null;
        }
        return byteFina;
    }

    /**
     * 解密以byte[]密文输入,以byte[]明文输出
     * 作者:陈嘉瑛
     * 时间:2015-04-11
     * @param byteD byte[]密文
     * @return byte[]明文
     */
    private byte[] getDesCode(byte[] byteD) {
        Cipher cipher;
        byte[] byteFina = null;
        try {
        	IvParameterSpec zeroIv = new IvParameterSpec(iv);
        	SecretKeySpec key = new SecretKeySpec(strKey.getBytes(), "DES");
        	cipher = Cipher.getInstance(TRANSFORMATION);
        	cipher.init(Cipher.DECRYPT_MODE, key, zeroIv);
            byteFina = cipher.doFinal(byteD);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            cipher = null;
        }
        return byteFina;
    }
}

action中代码:

代码语言:javascript复制
package com.ge.action;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import net.sf.json.JSONObject;
import org.apache.struts2.ServletActionContext;
import com.androidquery.AQuery;
import com.ge.dao.UsersDao;
import com.ge.entity.Users;
import com.ge.tool.ThreeDesUtil;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.opensymphony.xwork2.ActionContext;
public class LoginAction {
    private static String cryptKey = "12345678";
	private String username;
	private String password;
	private UsersDao usersdao;
	//利用spring进行依赖注入,不需要new 对象就可以实现数据的初始化。
	public void setUsersdao(UsersDao usersdao) {
		this.usersdao = usersdao;
	}
	
	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public String execute() throws IOException{
		//获取Server中的request和response.
		HttpServletRequest request = ServletActionContext.getRequest();
		HttpServletResponse response = ServletActionContext.getResponse();
		response.setCharacterEncoding("utf-8");
	    request.setCharacterEncoding("utf-8");
	    //获取从客户端传送过来的json数据
		String json=request.getParameter("json");
		System.out.println("解密前json.....>" json);
		ThreeDesUtil  des = new ThreeDesUtil();
        //生成密钥
        des.getKey(cryptKey);
        String content = des.getDesString(json);
        System.out.println("解密后json....>" content);
		   PrintWriter writer=response.getWriter();
		   String result="添加成功!!!";
		   writer.println(des.getEncString(result));
		   writer.flush();
		   writer.close(); 
		return "s";
	}
}

输出结果为:

代码语言:javascript复制
解密前json.....>XWB/lOUWrDHUoXb5HSxVzO/XZLoFpCl81Zb4TgaJ8GCayYCtjMioqA==
解密后json....>[{"password":"231","username":"112"}]

注意点:

1.Android端和后台所用的秘钥是必须是一样的。

2.本代码中有用到Android Aquery的ajax的知识,如果大家想要了解可以看利Android AQuery中ajax访问SSH搭建的后台Java Web服务器    http://blog.csdn.net/linzhiqiang0316/article/details/48369117。

0 人点赞