您的位置:首页 > 理论基础 > 计算机网络

网络传输安全--前端js加密后端java解密

2017-07-27 09:08 656 查看
摘要: 数据传输

很多网站或者很多数据传输中涉及到敏感数据,特别是面对互联网时,很多数据都要求安全和敏感,要求对数据进行安全处理,然后再网络上传输,保证数据的安全以及用户的隐私。所以很多系统都要求对敏感数据进行加密,特别是用户信息及密码信息或者其他的敏感数据。在互联网上,不管是app或者web都需要相应的安全机制保证数据的安全。

今天再这里将的主要是对称加密,说到对称加密就要说非对称加密,两个最大的区别是使用的秘钥,对称加密使用的秘钥是相同的,加密端和解密端都是使用想用的秘钥;非对称加密加密端和解密端使用的秘钥是不同的。java中常用的对称加密主要有:DES,3DES,AES。

首先简单的介绍一些常用的对称加密算法,这里只是简单的说明一下。DES:DES算法全称为Data Encryption Standard,即数据加密算法,它是IBM公司于1975年研究成功并公开发表的。DES算法的入口参数有三个:Key、Data、Mode。其中Key为8个字节共64位,是DES算法的工作密钥;Data也为8个字节64位,是要被加密或被解密的数据;Mode为DES的工作方式,有两种:加密或解密。3DES(或称为Triple DES)是三重数据加密算法(TDEA,Triple Data Encryption Algorithm)块密码的通称。它相当于是对每个数据应用三次DES加密算法。由于计算机运算能力的增强,原版DES密码的钥长度变得容易被暴力破解;3DES即是设计用来提供一种相对简单的方法,即通过增加DES的密钥长度来避免类似的攻击,而不是设计一种全新的块密码算法。

直接切入正题,本例中使用的是DES加密算法,前端使用js对数据加密,后端使用java对数据进行解密。

<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<c:set var="ctx" value="${pageContext.request.contextPath}"/>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<script type="text/javascript" src="${ctx}/webresource/js/jquery-1.9.1.min.js"></script>
<script type="text/javascript" src="${ctx}/webresource/js/core.js" ></script>
<script type="text/javascript" src="${ctx}/webresource/js/tripledes.js" ></script>
<script type="text/javascript" src="${ctx}/webresource/js/mode-ecb.js"></script>
</head>
<body>
<!--  本页面的功能是进行前端js加密,提交到后端,后端采用相同的算法进行解密 -->
<form id="form1" action="${ctx}/User/login/phone" method="post">
<!--  该秘钥可以在后期进行动态的生成,要求长度必须是8的倍数  -->
<input type="hidden" id="seckey" name="seckey" value="12345678"/>
key:<input type="text" name="key" value="${userSignupParam.key }" />
passwd:<input type="text" id="passwd" name="passwd" value="${userSignupParam.passwd }" />
phone:<input type="text" id="phone" name="phone" value="${userSignupParam.phone }" />

check:<input type="text" id="c
3ff0
heck" name="check" value="${userSignupParam.check }" />
<div>
<input type="button" value="save" name="save" onclick="submitForm();"/>
<input type="button" value="cancle" name="cancle" onclick="cancleForm();"/>
</div>
</form>

<script type="text/javascript">
function submitForm() {

var passwd = document.getElementById("passwd").value;
if (!passwd) {
return false;
}
var phone = document.getElementById("phone").value;
if (!phone) {
return false;
}
var check = document.getElementById("check").value;
if (!check) {
return false;
}

var newPasswd = encryptByDES(passwd, $("#seckey").val());
document.getElementById("passwd").value = newPasswd;

document.getElementById("form1").submit();

}

// DES加密
function encryptByDES(message, key) {
var keyHex = CryptoJS.enc.Utf8.parse(key);
var encrypted = CryptoJS.DES.encrypt(message, keyHex, {
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7
});
return encrypted.toString();
}
</script>
</body>
</html>

前端的加密依赖js可以在我开源的项目中找到,该页面的地址:https://git.oschina.net/gnn-wsx/ones/blob/master/ones-user/src/main/webapp/phonelogin.jsp?dir=0&filepath=ones-user%2Fsrc%2Fmain%2Fwebapp%2Fphonelogin.jsp&oid=f9672e685820adba43440a342602f184f182d16e&sha=bcb9f5f782ea27a848c4ba901c811271c854fe7a

然后后端进行数据的解密:

@RestController
@Scope("prototype")
public class PhoneLoginController extends UserBaseController {

private final static Logger log = LoggerFactory.getLogger(PhoneLoginController.class);

@RequestMapping(
value = "/login/phone",
method = {RequestMethod.POST}
)
public @ResponseBody OutputData phoneLogin(UserParam userParam) {
log.info("enter");

if (!checkLoginParam(userParam, UserLoginEnum.PHONE)) {
return new OutputData(WebController.CODE_ERROR_CLIENT, WebController.STATUS_ERROR_PARAM);
}

//解密的key后期可以动态的生成,并且做到安全,可以定期的更换,放置在redis中
String passwd = userParam.getPasswd();
String val = DESUtils.decryptDes(passwd,"12345678");

return new OutputData();
}
}

这个是做数据接收的api,下面是详细的数据加密解密操作:

package com.wsx.ones.core.secure;

import org.bouncycastle.util.encoders.Base64;

import javax.crypto.*;
import javax.crypto.spec.SecretKeySpec;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

/**
* 处理前端通过js进行des的加密处理,后端进行数据解密的操作
* Created by wangshuaixin on 17/1/19.
*/
public class DESUtils {

private static final String ALGORITHM_DES = "DES"; //定义 加密算法,可用 DES,DESede,Blowfish
//加密的key的长度必须是8的倍数,否则报错
private static final String PUBLIC_KEY = "_o_1op0ones_wvm8wsxvu_o6";

public static final String ENCODING = "UTF-8";

/**
* 加密操作,接收数组
* @param source 原文
* @param seckey 秘钥
* @return
*/
public static byte[] encryptDes(byte[] source, byte[] seckey) {

Cipher cipher = null;
try {
SecretKey secretKey = new SecretKeySpec(seckey, ALGORITHM_DES);
cipher = Cipher.getInstance(ALGORITHM_DES);

cipher.init(Cipher.ENCRYPT_MODE, secretKey);

return cipher.doFinal(source);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
}

return null;
}

/**
* 解密处理
* @param source 密文
* @param seckey 秘钥
* @return
*/
public static byte[] decryptDes(byte[] source, byte[] seckey) {

Cipher cipher = null;
try {
SecretKey secretKey = new SecretKeySpec(seckey, ALGORITHM_DES);
cipher = Cipher.getInstance(ALGORITHM_DES);

cipher.init(Cipher.DECRYPT_MODE, secretKey);

return cipher.doFinal(source);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
}
return null;
}

/**
* 加密处理,接收的和返回的都是字符串,便于系统中的操作和转换
* @param source 原文
* @param key 秘钥
* @return
*/
public static String encryptDes(String source, String key) {
try {
byte[] src = source.getBytes(ENCODING);
byte[] keys = key.getBytes(ENCODING);
return new String(Base64.encode(decryptDes(src, keys)));
} catch (Exception e) {
e.printStackTrace();
}
return null;
}

/**
* 解密操作,接收的返回的都是字符串
* @param source 密文
* @param key 秘钥
* @return
*/
public static String decryptDes(String source, String key) {
try {
byte[] src = source.getBytes(ENCODING);
byte[] keys = key.getBytes(ENCODING);
return new String(decryptDes(Base64.decode(src),keys), ENCODING);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}

@Deprecated
public static void main(String[] args) throws Exception {
//秘钥必须是8的倍数
String key = "12345678";
String source = "wsx123456";

byte[] sec = encryptDes(source.getBytes(ENCODING), key.getBytes(ENCODING));

String newVal = new String(Base64.encode(sec),ENCODING);

byte[] origin = decryptDes(Base64.decode(newVal.getBytes(ENCODING)), key.getBytes(ENCODING));

String oriVal = new String(origin, ENCODING);

System.out.print(oriVal);

//P3OXNkyYf7sRUsQcU35IoQ==
//zlN2U/tBCeK8gS3zNjQJ0w==

//fCVIf1V/Bn4xhcIxeOGSZQ==
//fCVIf1V/Bn4xhcIxeOGSZQ==
}
}

后端的源码地址及依赖的jar包可以在项目中找到,主要是依赖Base64的编码解码来操作。
https://git.oschina.net/gnn-wsx/ones/blob/master/ones-user/src/main/java/com/wsx/ones/user/login/PhoneLoginController.java?dir=0&filepath=ones-user%2Fsrc%2Fmain%2Fjava%2Fcom%2Fwsx%2Fones%2Fuser%2Flogin%2FPhoneLoginController.java&oid=d1e5bf6fe2389c7707d394d762c645851aac0f9c&sha=bcb9f5f782ea27a848c4ba901c811271c854fe7a
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息