LZ第一次给app写开放接口,把自己处理Token的实现记录下来,目的是如果以后遇到好的实现,能在此基础上改进。这一版写法非常粗糙,写出来就是让大家批评的,多多指教,感谢大家。
当初设计这块想达到的效果或者说考虑到的问题有这么几点:
首先是token的模型:
再来就是TokenModel的管理类:
/***对Token进行操作的接口*@authorxiaodong*/publicinterfaceTokenManager{/***创建一个token关联上指定用户*@paramuserId指定用户的id*@return生成的token*/TokenModelcreateToken(StringuserId);/***检查token是否有效*@parammodeltoken*@return是否有效*/booleancheckToken(TokenModelmodel);/***清除token*/voiddeleteToken(StringaccessToken);}该接口实现:
这样做好处是:
缺点:
我把剩余的ResultModel类补上。
=================2019.04.17追加=================
重新审视这个问题。
第一种是传统的办法,使用自签名证书,借用jdk和web容器的ssl层实现,这种方法比较常用,也比较省事。
第二种是手动编程的方法,类似于自己写了一层ssl的实现。原理也很简单,对方把数据加密后传给LZ的服务端,LZ这边解密后该怎么处理就怎么处理,完事以后把响应的数据加密传给客户端,客户端解密之后该怎么处理就怎么处理。
经过一番实验和思考,LZ还是决定采用第二种方法。主要原因是,这种方式更加灵活,加密方案是LZ可以随意更改的(比如把其中的某个算法用别的算法替换)。还有一点原因是,自己写的东西更加容易掌控,如果加密层出现问题,LZ作为PM可以更快的定位问题。最后一点原因是,基于算法而不是基于Java类库,更容易制作各种语言的客户端。
方案基本确定,接下来就是代码设计。代码设计分为客户端和服务端,作为客户端,LZ可以提供公用的加密解密组件给合作伙伴调用(比如java客户端,php客户端,.NET客户端等等)。作为服务端,LZ只需要过滤器和定制视图就可以轻易完成加密和解密的工作。
最终写出来的客户端API如下:
HttpsHelper.sendJsonAndGetJson(JSONObjectjson);
HttpsHelper.sendJsonAndGetJson(JSONObjectjson,inttimeout);
服务端需要一个过滤器和一个定制的json视图。
SecurityFilter
JsonView
由于LZ发布的是restful风格的服务,因此使用的mvc框架是springmvc。这两个类的具体代码这里就不贴了,总之过滤器完成请求参数的解密,视图完成响应结果的加密。
以上基本上已经完成了整个加密解密功能的设计,接下来的工作就是将工作落实到实处,到底加密算法如何选择?
之前LZ对加密解密算法可谓是大大的小白,就知道一个md5算法,一般是用于密码加密的。这下可难倒LZ了,不过没关系,有百度和google,还有什么不能在几天之内学到的东西吗。
经过一番百度和google,LZ发现算法主要分为以下三种:
1,不可逆加密算法,比如md5就是这样一种,这种算法一般用于校验,比如校验用户的密码对不对。
2,对称加密算法,这种算法是可逆的,两边拥有同一个密钥,使用这个密钥可以对数据加密和解密,一般用于数据加密传输。特点是速度快,但安全性相对于非对称加密较低。
3,非对称加密算法,这种算法依然是可逆的,两边拥有不同的密钥,一个叫公钥,一个叫私钥,两边也都可以对数据加密和解密,一般用于数字签名。特点是速度较慢,但安全性相对于对称加密更高。
之前LZ听说过ssl的实现是几种算法混合使用的,这给了LZ很大的启示。既然每种算法都有它的优势,我们为何不混合使用呢。
于是,LZ想来想去(主要是在公车上以及厕所思考),决定使用md5(不可逆加密)+des(对称加密)+rsa(非对称加密)的加密方式,编码格式可以使用Base64。来看看LZ的需求,主要有两点。
2,数据在传输过程中是加密的,并且安全性要等同于非对称加密算法的安全性,但性能要等同于对称加密的速度。
我们来看看以上的算法实现能否满足需要,过程是这样的。
2,客户端需要先对123456进行md5加密,然后放入到传输数据中。也就是传输的数据会变成{"name":"xiaolongzuo","verifyCode":"md5(123456)"}
3,客户端生成des的随机密钥(注意,对称密钥每次都是随机生成的),假设是abcdef,客户端使用该密钥对传输数据进行des加密,并且对随机密钥进行rsa加密,最终拼成一个json。也就是最终传输的数据会变成{"privateKey":"rsa(abcdef)","data":"des({"name":"xiaolongzuo","verifyCode":"md5(123456)"})"}
安全性分析:假设以上的数据被黑客拦截,那么黑客最主要做的就是破解rsa算法的私钥(私钥只有LZ有,客户端组件中会附带公钥),这个问题听说是比较难的,具体为什么,这就不是LZ需要考虑的了,LZ还没这个能力。基于这个前提,LZ可以认为传输的数据还是比较安全的。
性能分析:由于我们的rsa只对长度比较短的des私钥进行加密,因此非对称加密速度慢的特点并不会影响我们太多。几乎上所有的传输数据,我们都是使用的des进行加密,因此在速度上,几乎等同于对称加密的速度。