-
项目背景:
为了安全起见,后台框架采用严密的加解密算法使我们的数据传输更加的安全。同时我们也进行了数据传输过程中的数据压缩和用户的签名验证等等...,算是最这些的一个小小的总结吧!
-
算法介绍:
(1)MD5算法:
《1》算法介绍:
MD5:输入任意长度的信息,输出为128位的信息(数字指纹);不同的输入得到不同的结果(唯一性).
《2》主要用途:
1)防止被篡改:
比如发送一个电子文档,发送前,我先得到MD5的输出结果a。然后在对方收到电子文档后,对方也得到一个MD5的输出结果b。如果a与b一样就代表中途未被篡改。2)比如我提供文件下载,为了防止不法分子在安装程序中添加木马,我可以在网站上公布由安装文件得到的MD5输出结果。3)SVN在检测文件是否在CheckOut后被修改过,也是用到了MD5.2)防止直接看到明文:
现在很多网站在数据库存储用户的密码的时候都是存储用户密码的MD5值。这样就算不法分子得到数据库的用户密码的MD5值,也无法知道用户的密码(其实这样是不安全的,后面我会提到)。(比如在UNIX系统中用户的密码就是以MD5(或其它类似的算法)经加密后存储在文件系统中。当用户登录的时候,系统把用户输入的密码计算成MD5值,然后再去和保存在文件系统中的MD5值进行比较,进而确定输入的密码是否正确。通过这样的步骤,系统在并不知道用户密码的明码的情况下就可以确定用户登录系统的合法性。这不但可以避免用户的密码被具有系统管理员权限的用户知道,而且还在一定程度上增加了密码被破解的难度。)3)防止抵赖(数字签名):
这需要一个第三方认证机构。例如A写了一个文件,认证机构对此文件用MD5算法产生摘要信息并做好记录。若以后A说这文件不是他写的,权威机构只需对此文件重新产生摘要信息,然后跟记录在册的摘要信息进行比对,相同的话,就证明是A写的了。这就是所谓的“数字签名”。(2).RSA:典型的非对称算法:
《1》算法介绍:
它是一种典型的非对称性的加密算法。如下图所示:
《2》主要用途:
这种算法1978年就出现了,它是第一个既能用于数据加密也能用于数字签名的算法。它易于理解和操作,也很流行。
(3).AES算法:
《1》算法介绍:
密码学中的高级加密标准算法,是一种实用性的对称加解密算法,下一代加密算法标准,速度快,安全级别高.
《2》主要用途:
保密性:防止用户的标识或数据被读取。
数据完整性:防止数据被更改。
身份验证:确保数据发自特定的一方。
3. 项目实际使用情况介绍:
注意:api_version的作用是如果黑客知道了我们的RSA算的公钥和私钥,我们会直接升级API版本,然后发送大家推送消息。升级!这样我们的服务器就会再次生成一对公钥和私钥!
expires的作用是签名验证的时候设置认证时间!
例子:
String requestData = request.getParameter(ConstantField.API_PARAMS);
// 加密后的数据
String timestamp = request.getParameter(ConstantField.SIGN_TIMESTAP);
String api_version = request
.getParameter(ConstantField.SIGN_API_VERSION);
String secret_key = request.getParameter(ConstantField.SIGN_AES_KEY);
String sign = request.getParameter(ConstantField.API_SIGN);
String httpMethod = httpRequest.getMethod();
StringBuffer url = httpRequest.getRequestURL();
long
expires =
0
;
try
{
expires = Long.valueOf(request
.getParameter(ConstantField.SIGN_EXPIRES));
}
catch
(Exception e) {
expires =
0
;
}
// 提取Session绑定的秘钥
HttpSession session = httpRequest.getSession(
true
);
String aes_secret_key = String.valueOf(session
.getAttribute(ConstantField.SIGN_AES_KEY));
// aes_secret_key
// 用户是否切换动态密钥,是新密要解密
if
(enable_cryptic
&& secret_key !=
null
&& !secret_key.equals(String.valueOf(session
.getAttribute(ConstantField.SIGN_RSA_KEY)))) {
aes_secret_key = RSAUtils.decrypt(secret_key, RSA.getPrivateKey());
// 记录用户AES秘钥,加密后密钥和明文密钥均记录
session.setAttribute(ConstantField.SIGN_AES_KEY, aes_secret_key);
session.setAttribute(ConstantField.SIGN_RSA_KEY, secret_key);
}
// 验签认证
Status status = SignAuthUtil.verifySign(httpMethod, url, requestData,
timestamp, expires, api_version, aes_secret_key, sign);
if
(enable_sing_auth && Status.SUCCESS != status) {
writeResponse(httpResponse, status);
return
;
}
// 数据解密处理
if
(enable_cryptic && requestData !=
null
&& !
""
.equals(requestData)) {
try
{
paramMap.put(ConstantField.API_PARAMS,
AESUtils.decrypt(aes_secret_key, requestData));
}
catch
(Exception e) {
e.printStackTrace();
}
}
// 根据请求设置返回数据格式HTTP head
responseWrapper.setContentType(
"text/json;charset="
+ encoding);
responseWrapper.setCharacterEncoding(encoding);
chain.doFilter(
new
ParameterRequestWrapper(httpRequest, paramMap),
responseWrapper);
// 数据给action