一次ssl的手动实现——加密算法的简单扫荡
引言
最近LZ在公司里接了一个活,要发布一些服务给公司的合作伙伴调用。这种工作LZ可谓是轻车熟路,之前已经做了无数服务端。不过与以往不同的是,这次的服务是要发布在互联网上的,因此不能再像之前的套路一样。之前的系统交互都是公司内网之间的,因此不存在数据安全问题。
这次不得不考虑数据的安全性,因此LZ最近就苦逼的开始研究各种加密算法。前后一共用了三天时间,LZ终于把加密层做好了,尽管LZ对各种加密算法的原理一概不知,但应该也算够用了。毕竟LZ没打算做一个绝对安全的系统(事实上这也是不可能的),只要能阻止90%的黑客即可。
方案制定
开始的时候,首先要制定方案,应用层的协议采用http,这点是确定的。对于加密,LZ想来想去,基本上有两种选择。
第一种是传统的办法,使用自签名证书,借用jdk和web容器的ssl层实现,这种方法比较常用,也比较省事。
第二种是手动编程的方法,类似于自己写了一层ssl的实现。原理也很简单,对方把数据加密后传给LZ的服务端,LZ这边解密后该怎么处理就怎么处理,完事以后把响应的数据加密传给客户端,客户端解密之后该怎么处理就怎么处理。
经过一番实验和思考,LZ还是决定采用第二种方法。主要原因是,这种方式更加灵活,加密方案是LZ可以随意更改的(比如把其中的某个算法用别的算法替换)。还有一点原因是,自己写的东西更加容易掌控,如果加密层出现问题,LZ作为PM可以更快的定位问题。最后一点原因是,基于算法而不是基于Java类库,更容易制作各种语言的客户端。
代码设计
方案基本确定,接下来就是代码设计。代码设计分为客户端和服务端,作为客户端,LZ可以提供公用的加密解密组件给合作伙伴调用(比如java客户端,php客户端,.NET客户端等等)。作为服务端,LZ只需要过滤器和定制视图就可以轻易完成加密和解密的工作。
最终写出来的客户端API如下:
HttpsHelper.sendJsonAndGetJson(JSONObject json);
HttpsHelper.sendJsonAndGetJson(JSONObject json,int timeout);
以上就是客户端组件公布的两个方法,方法的作用很好理解,LZ就不多说了。在方法的实现当中,LZ已经帮客户端完成了加密和解密操作。当然,使用这个客户端的前提是,得到LZ给予的授权码。
服务端需要一个过滤器和一个定制的json视图。
SecurityFilter
JsonView
由于LZ发布的是restful风格的服务,因此使用的mvc框架是spring mvc。这两个类的具体代码这里就不贴了,总之过滤器完成请求参数的解密,视图完成响应结果的加密。
ssl层实现
以上基本上已经完成了整个加密解密功能的设计,接下来的工作就是将工作落实到实处,到底加密算法如何选择?
之前LZ对加密解密算法可谓是大大的小白,就知道一个md5算法,一般是用于密码加密的。这下可难倒LZ了,不过没关系,有百度和google,还有什么不能在几天之内学到的东西吗。
经过一番百度和google,LZ发现算法主要分为以下三种:
1,不可逆加密算法,比如md5就是这样一种,这种算法一般用于校验,比如校验用户的密码对不对。
2,对称加密算法,这种算法是可逆的,两边拥有同一个密钥,使用这个密钥可以对数据加密和解密,一般用于数据加密传输。特点是速度快,但安全性相对于非对称加密较低。
3,非对称加密算法,这种算法依然是可逆的,两边拥有不同的密钥,一个叫公钥,一个叫私钥,两边也都可以对数据加密和解密,一般用于数字签名。特点是速度较慢,但安全性相对于对称加密更高。
之前LZ听说过ssl的实现是几种算法混合使用的,这给了LZ很大的启示。既然每种算法都有它的优势,我们为何不混合使用呢。
于是,LZ想来想去(主要是在公车上以及厕所思考),决定使用md5(不可逆加密)+des(对称加密)+rsa(非对称加密)的加密方式,编码格式可以使用Base64。来看看LZ的需求,主要有两点。
1,客户端需要LZ授权,也就是说LZ发布的服务不是谁想调就能调的。
2,数据在传输过程中是加密的,并且安全性要等同于非对称加密算法的安全性,但性能要等同于对称加密的速度。
我们来看看以上的算法实现能否满足需要,过程是这样的。
1,假设LZ给客户端一个授权码,比如123456。再假设客户端现在需要传的数据是{"name":"xiaolongzuo"}。(请求数据和响应数据都是json格式)
2,客户端需要先对123456进行md5加密,然后放入到传输数据中。也就是传输的数据会变成{"name":"xiaolongzuo","verifyCode":"md5(123456)"}
3,客户端生成des的随机密钥(注意,对称密钥每次都是随机生成的),假设是abcdef,客户端使用该密钥对传输数据进行des加密,并且对随机密钥进行rsa加密,最终拼成一个json。也就是最终传输的数据会变成{"privateKey":"rsa(abcdef)","data":"des({"name":"xiaolongzuo","verifyCode":"md5(123456)"})"}
4,服务端使用相反的过程对数据进行解密即可,并验证解密后的授权码md5(123456)是否存在,如果不存在,则认为该客户端未被授权。当服务端返回数据时,依旧使用abcdef对数据进行des加密即可。
安全性分析:假设以上的数据被黑客拦截,那么黑客最主要做的就是破解rsa算法的私钥(私钥只有LZ有,客户端组件中会附带公钥),这个问题听说是比较难的,具体为什么,这就不是LZ需要考虑的了,LZ还没这个能力。基于这个前提,LZ可以认为传输的数据还是比较安全的。
性能分析:由于我们的rsa只对长度比较短的des私钥进行加密,因此非对称加密速度慢的特点并不会影响我们太多。几乎上所有的传输数据,我们都是使用的des进行加密,因此在速度上,几乎等同于对称加密的速度。
小结
由于源代码是公司所有,因此LZ这里不方便贴出来,但是整个思路这里已经阐述的非常清晰了。
通过这次的简单学习,也不难发现,带着目的的学习才是最高效率的学习。试想一下,如果LZ只是闲来无事,随便看看加密算法,相信不会在这么短的时间内搞清楚,并且学会一些基础的使用方法。所以事实证明,学习任何知识,最好的办法就是利用这个知识做一个东西出来。
一次ssl的手动实现——加密算法的简单扫荡的更多相关文章
- SSL握手两大加密算法 : RAS算法 和 DH算法解析
写下此博客记录心得体会,如有不足之处请指正 先是手稿笔记 : 正文: 在Https协议中,Client端和Server端需要三个参数才能生成SessionKey来加密信息. 三个参数分别是 ...
- RSA加密算法的简单案例
RSA加密算法是目前最有影响力的公钥加密算法,它能够抵抗到目前为止已知的绝大多数密码攻击. 那关于RSA加密算法有哪些应用呢?以下举一个数据库身份验证的案例. 在使用数据集进行身份认证时,密码存在数据 ...
- C#手动回收内存的简单方法
C#有自动回收内存的机制,但是有时自动回收有一定滞后,需要在变量使用后迅速回收,节约内存,这里介绍一个最简单的方法. 1.先对对象赋值 null; 2.System.GC.Collect(); 代码样 ...
- 使用SSL配置Nginx反向代理的简单指南
反向代理是一个服务器,它接收通过Web发出的请求,即http和https,然后将它们发送到后端服务器(或服务器).后端服务器可以是单个或一组应用服务器,如Tomcat,wildfly或Jenkins等 ...
- 《TensorFlow2深度学习》学习笔记(二)手动搭建并测试简单神经网络(附mnist.npz下载方式)
本实验使用了mnist.npz数据集,可以使用在线方式导入,但是我在下载过程中老是因为网络原因被打断,因此使用离线方式导入,离线包已传至github方便大家下载: https://github.com ...
- RSA加密算法c++简单实现
RSA是一种非对称加密算法,在公开密钥和电子商业中RSA被广泛使用.它是基于一个很简单的数论事实,两个素数相乘很容易,对两素数乘积因式分解很困难.原理就不再阐述了,我谈谈算法的编程实现过程. 一.RS ...
- 使用md5加密算法完成简单的登录和注册功能
原理: 登录:后端controller层获取到客户的密码,通过下面代码:new Sha256Hash(pwd).toHex();将密码转换成md5散列,生成一个新的字符串与数据库的值进行比对,根据不同 ...
- 浅析nodeJS中的Crypto模块,包括hash算法,HMAC算法,加密算法知识,SSL协议
node.js的crypto在0.8版本,这个模块的主要功能是加密解密. node利用 OpenSSL库(https://www.openssl.org/source/)来实现它的加密技术, 这是因为 ...
- SSL / TSL 传输加密算法 初解读
SSL(SecureSocketLayer)是netscape公司提出的主要用于web的安全通信标准,.TLS(TransportLayerSecurity)是IETF的TLS工作组在SSL3.0基础 ...
随机推荐
- 【DPDK】虚拟机开发环境配置
DPDK介绍见:www.dpdk.org 本文介绍的步骤基本适用于dpdk 1.7.0 - dpdk 2.0.0 各版本.只是setup.sh显示的菜单有一些小的不同:同样的,也适用于ubuntu更高 ...
- powerdesigner设置表主键列为自动增长
powerdesigner 版本12.5 创建表就不说了.下面开始介绍设置自动增长列. 1 在表视图的列上创建.双击表视图,打开table properties ———>columens ,双击 ...
- 计算1到最大的n位十进制数 ——大数解决
要求:输入一个数字n,按照顺序打印出从1到最大的n为十进制.比如输入3,则打印出1.2.3……一直到最大的3位数999 这个看起来好像很简单啊.巴拉巴拉,已经得出了下面的代码 /** * 注意: 错误 ...
- C++ 第一个C++程序
#include <iostream> // C++自带的标准头文件都是没有.h的 // 就相当于C语言的<stdio.h> // 提前使用命名空间std using name ...
- UESTC 919 SOUND OF DESTINY --二分图最大匹配+匈牙利算法
二分图最大匹配的匈牙利算法模板题. 由题目易知,需求二分图的最大匹配数,采取匈牙利算法,并采用邻接表来存储边,用邻接矩阵会超时,因为邻接表复杂度O(nm),而邻接矩阵最坏情况下复杂度可达O(n^3). ...
- C/C++学习----C语言简介
[开发环境] 物理机版本:Win 7 旗舰版(64位) IDE版本:Visual Studio 2013简体中文旗舰版(cn_visual_studio_ultimate_2013_with_upda ...
- JavaWeb学习之Servlet(二)----Servlet的生命周期、继承结构、修改Servlet模板
[声明] 欢迎转载,但请保留文章原始出处→_→ 文章来源:http://www.cnblogs.com/smyhvae/p/4140466.html 一.http协议回顾: 在上一篇文章中:JavaW ...
- Wooyun隐写术总结
之前还没有见到drops上有关于隐写术的总结,我之前对于隐写术比较有兴趣,感觉隐写术比较的好玩.所以就打算总结总结一些隐写术方面的东西.写的时候,可能会有错误的地方,请不吝赐教,谢谢. 本篇章中用到的 ...
- Block 的基本用法
iOS中Block的基础用法 转载自简书 本文简介 本章不会对Block做过多的实现研究.只是讲解基本的用法.纯粹基础知识.结合实际项目怎么去做举例.Block使用场景,可以在两个界面的传值,也可以对 ...
- ST3插件——PlainTasks的使用
今天看到一个有意思的ST3插件,可以进行简单的任务管理. 安装很简单:ctrl + shift + p,输入install回车,再输入plaintasks回车即可. 以下是一些支持的操作,更多的操作请 ...