建立RSA协商加密的安全信道
在基于TCP长连接的CS链路中,如何保证数据流的安全性是开发者最关注的问题之一。本文深入浅出的给大家介绍一下在TCP连接中,使用RSA协商加密的方式,建立一个安全加密的通信链路,保证数据传输的安全性。文章分为3个主要部分,即RSA算法简介,安全信道协商流程详解和一些工程优化方法。期望大家在读了我这篇文章之后能够透彻的理解基于RSA协商加密方式的信道建立方式并能够运用在自己的业务实践中。
RSA算法简介
加密算法是计算机通信安全的基石,加密算法分为2个大类,即”对称加密算法“和”非对称加密算法“。”对称加密算法“的缺点比较明显,即甲方必须把加密规则告诉乙方,否则无法解密。因此保存和传递密钥,就成了最头疼的问题。本文所依赖的加密算法RSA算法是一种”非对称加密算法“,其具有以下特点:
- 乙方生成两把密钥(公钥和私钥)。公钥是公开的,任何人都可以获得,私钥则是保密的。
- 甲方获取乙方的公钥,然后用它对信息加密。
- 乙方得到加密后的信息,用私钥解密。
其实关键知识点就是:用公钥加密,用私钥解密,私钥要做好保密。
RSA算法的原理可以参照阮一峰的博文:http://www.ruanyifeng.com/blog/2013/06/rsa_algorithm_part_one.html 和 http://www.ruanyifeng.com/blog/2013/07/rsa_algorithm_part_two.html
安全信道协商流程
我们选择使用RSA加密算法建立安全信道,在介绍具体方法之前,我们先约定几个术语:
- C表示客户端(Client)
- S表示服务端(Server)
- priKey表示私钥(PrivateKey)
- pubKey表示公钥(PublicKey)
下面分步骤对流程进行详细描述。
前提说明
在安全信道建立之前,客户端和服务端已经拥有一套公私钥对,公钥由客户端持有,私钥由服务端持有。这里的公私钥分别表示为:pubKey0和priKey0.
C->S传递pubKey
- 客户端生成一对公私钥,分别表示为pubKeyC和priKeyC,其中priKeyC客户端自己持有,pubKeyC需要传递给服务端;
- 客户端使用pubKey0对pubKeyC进行加密,然后通过TCP链路将加密后的数据传输给服务端;(这个过程我们称为Stage1)
- 服务端收到客户端加密的信息后,使用priKey0对信息进行解密,得到pubKeyC.
S->C传递pubKey
- 服务端生成一对公私钥,分别表示为pubKeyS和priKeyS,其中priKeyS服务端自己持有,pubKeyS需要传递给客户端;
- 服务端使用pubKeyC对pubKeyS进行加密,然后通过TCP链路将加密后的数据传输给客户端;(这个过程我们称为Stage3)
- 客户端收到服务端加密的信息后,使用priKeyC对信息进行解密,得到pubKeyS.
加密通信
经过上述全双工的加密协商过程,客户端和服务端之间就建立了使用RSA算法进行加密的通信信道,后续的数据传输就是在上述安全信道下进行的。具体如下:
- C-->S的数据,在C端加密,在S端解密,使用的是由服务端初始化生成的公私钥对(pubKeyS和priKeyS);
- S-->C的数据,在S端加密,在C端解密,使用的是由客户端初始化生成的公私钥对(pubKeyC和priKeyC).
工程实践中的一些优化点
尽量降低初始化私钥priKey0泄漏风险
上述公私钥协商过程的安全性是建立在初始化私钥,即服务端所持有的priKey0未泄漏的基础上的。如果priKey0泄漏了,那么理论上这个”安全“信道就不安全了。一般工程实践中,会通过2中方式去尽量降低私钥泄漏风险:
- 将初始化公私钥对从一对扩展到多对,在Stage1的过程中,选择某一个公钥对数据进行加密,同时将公钥索引追加到传递给服务端的信息中去。服务端在收到信息后先解析出索引,然后取出对应的私钥进行解密;
- 不定期的更新公私钥对,这种方案会有一定的弊端,服务端需要同时维护针对不同客户端版本的私钥信息,并且还要额外增加一个字段标识服务端使用那对私钥进行解密,不过可以通过控制客户端版本数量的方式,将维护成本降低,如维护2个版本客户端,其他版本强制退出。
服务端Stage3初始化公私钥性能
对于客户端来说,每次建立安全通道,单个客户端只需要进行一次公私钥对的初始化计算,性能不是瓶颈。但是,对于服务端来说,尤其是接入层,服务了众多TCP长连接,如果频繁的进行公私钥对的初始化计算,CPU性能的消耗成本是巨大的。所以一般工程实践中,会选择一种更为理性的方案。
具体做法可以是:
- 在服务端启动的时候,预先初始化多对公私钥对,如可以初始化128对或者更多,然后将这些公私钥对保存在内存中。
- 在Stage3阶段,服务端不即时生成公私钥对,只需要随机选择一个内存中的一对公私钥,并进行加密操作,将对应的公钥传递给客户端即可。
以上,就是本文的所有内容,期望大家看了之后能有所收获,谢谢大家!
建立RSA协商加密的安全信道的更多相关文章
- SSL/TLS/WTLS原理(密钥协商的形象化比喻:验证服务器的身份,用服务器的公钥协商加密格式,然后再加密具体的消息,TCP传递SSL处理后的数据)good
一 前言 首先要澄清一下名字的混淆: 1 SSL(Secure Socket Layer)是netscape公司设计的主要用于web的安全传输协议.这种协议在WEB上获得了广泛的应用. 2 IETF( ...
- WebSocket数据加密——AES与RSA混合加密
前言 之前在写“一套简单的web即时通讯”,写到第三版的时候没什么思路,正好微信公众号看到一篇讲API交互加密,于是就自己搞了一套AES与RSA混合加密,无意中产生应用在WebSocket想法,好在思 ...
- 密码疑云 (3)——详解RSA的加密与解密
上一篇文章介绍了RSA涉及的数学知识,本章将应用这些知识详解RSA的加密与解密. RSA算法的密钥生成过程 密钥的生成是RSA算法的核心,它的密钥对生成过程如下: 1. 选择两个不相等的大素数p和q, ...
- 我的Android进阶之旅------>Android采用AES+RSA的加密机制对http请求进行加密
前言 未加密的抓包截图 加密之后的抓包截图 基本需求及概念 AES算法 AES基本原理及算法流程 AES算法流程 RSA算法 RSA算法基本原理及流程 RSA算法实现流程 AES与RSA相结合数据加密 ...
- Atitit RSA非对称加密原理与解决方案
Atitit RSA非对称加密原理与解决方案 1.1. 一.一点历史 1 1.2. 八.加密和解密 2 1.3. 二.基于RSA的消息传递机制 3 1.4. 基于rsa的授权验证机器码 4 1.5. ...
- CryptoAPI与openssl RSA非对称加密解密(PKCS1 PADDING)交互
(以下代码中都只做测试用,有些地方没有释放内存...这个自己解决下) 1.RSA非对称的,首先提供一个供测试用的证书和私钥的数据 1)pem格式的证书和私钥(公私钥是对应的)的base64编码 voi ...
- RSA算法加密解密
该工具类中用到了BASE64,需要借助第三方类库:javabase64-1.3.1. jar 注意:RSA加密明文最大长度117字节,解密要求密文最大长度为128字节,所以在加密和解密的过程中需要分块 ...
- RSA非对称加密Java实现
原文 加密基础方法类 import java.security.MessageDigest; import sun.misc.BASE64Decoder; import sun.misc.BASE64 ...
- RSA非对称加密简析-java
1 非对称加密算法 1.1 概述 1976年,美国学者Dime和Henman为解决信息公开传送和密钥管理问题,提出一种新的密钥交换协议,允许在不安全的媒体上的通讯双方交换信息,安全地达成一致的密钥,这 ...
随机推荐
- Java TCP通信
1.Socket原理 1)Socket简介 socket通常称作“套接字”,用于描述IP地址和端口号,是一个通信链的句柄.在Internet上的主机一般运行了多个服务软件,同时提供几种服务.每种服务都 ...
- SQLSTATE=42000 #42000
在使用PowerDesigner生成数据库表的时候遇到了这个问题. 原来是在填写属性的类型的时候, 少了两个括号, 造成了mysql数据类型错误 本来应该是varchar(50)的,写成了varcha ...
- VS快捷键总结(开发中经常遇到)
1.窗口快捷键 (大家有没有发现但凡跟窗口挂上钩的快捷键当中都有一个W,那是因为W代表Windows也就是窗口的意思) Ctrl+W,W: 浏览器窗口 (浏览橱窗用有道的翻译是window shop ...
- 使用filter函数筛选出素数
function getPrimeNumber(arr) { return arr.filter(function (number) { if (typeof number !== 'number' ...
- C语言中声明和定义详解(待看。。
变量声明和变量定义 变量定义:用于为变量分配存储空间,还可为变量指定初始值.程序中,变量有且仅有一个定义. 变量声明:用于向程序表明变量的类型和名字. 定义也是声明,extern声明不是定义 定义也是 ...
- Vue实例和生命周期
创建一个Vue实例 每个Vue应用都是通过Vue函数创建一个新的Vue实例开始: var vm = new Vue({ //选项 }) 数据与方法 当一个Vue实例被创建时,它向Vue的响应式系统中加 ...
- PHP获取文件夹内所有文件包括子目录文件的名称或路径
/* * new getFile($_dir[,$_emptyDir,$_fileType]); * @parma $_dir 是目录名称 * @parma $_emptyDir 是否获取空文件夹,选 ...
- Django ORM (三) 查询,删除,更新操作
ORM 查询操作 修改 views.py 文件 from django.shortcuts import render, HttpResponse from app01 import models f ...
- manjaro中virtualbox(vbox)配置
一.更新源的配置: 1).自动方法: 在 终端 执行下面的arch" style="color: #002be5">命令从官方的源列表中对中国源进行测速和设置 su ...
- leetcode-8-pointer
void deleteNode(ListNode* node) { *node = *node->next; }