加密算法有很多,如不可逆的摘要算法MD5、SHA(安全哈希算法),可逆的Base64编码,对称加密算法DES、AES,还有非对称加密算法DH、RSA等。那是不是说明我们可以使用任何一种加密算法就能保证网站的安全性,答案是否。举个例子,我们在登录web页面时,发送用户名和密码给服务器,这时请求被拦截了:

(1) 密码采用不可逆加密。因为不可逆加密算法就几种,不管怎样变换,攻击者都可以模拟登录;

(2) 密码采用可逆加密算法。因为加密是在前端进行加密,所以可能通过js代码看到加密方式,这样也就很容易破解了。

所以针对浏览器-服务器这种模式,最好采用非对称加密算法,即使攻击者知道了加密算法和公钥,他也没法解密,因为用公钥加密的数据只能用私钥才能解密,而且私钥始终保存在服务器,攻击者无法获取。

今天总结一下项目中使用非对称加密算法RSA实现登录验证的过程。

一、RSA非对称加密算法介绍

RSA加密算法是一种非对称加密算法,在甲乙方的通信过程中,首先甲方(通常是服务端)会生成一对秘钥对,称作公钥(Public Key)和私钥(Private Key),然后他把生成的公钥或私钥发送给乙方(客户端),乙方获取到公钥或私钥之后,用它将原始数据加密后发送给甲方,此时甲方用私钥或公钥对乙方发送过来的加密数据进行解密,在整个通信过程中,即使请求被拦截,攻击者获取到了暴露的秘钥和加密数据也无法解密,因为只能使用甲方手中的私钥才能解密,而在整个通信过程中私钥始终保存在甲方手中,没有在通信过程中传递,所以攻击者也就很难获取到,除非是甲方有意暴露。如下图所示:

上图的过程描述为:

1、  web服务器生成密钥对

2、  客户端(浏览器)从服务器获取公钥

3、  客户端用获取的公钥对原始数据加密后发送给web服务器

4、  Web服务器接受加密后的数据并获取到私钥

5、  Web服务器用私钥对数据进行解密

在上图中,采用的是公钥加密,私钥解密,还可以使用私钥加密,公钥解密的方式,关键是服务器只暴露其中的一个秘钥给客户端进行加密,另一个自己保存用来解密。

二、用PHP实现RSA加解密过程

第一步:生成密钥文件(公钥和私钥)

注:在生成秘钥对之前,需要在linux系统中安装openssl。

1、生成私钥文件

2、利用私钥生成公钥文件

3、秘钥文件生成结果

第二步:生成密钥对(公钥和私钥)

1、根据私钥文件生成私钥

function get_private_key() {
return @file_get_contents(DATA_PATH . 'Cert/rsa_private_key.pem');
}

2、根据公钥文件生成公钥

function get_public_key() {
return @file_get_contents(DATA_PATH . 'Cert/rsa_public_key.pem');
}

第三步:封装加密解密方法

1、公钥加密

/**
* 公钥加密
*/
function rsa_encrypt($string) {
$publicKey = get_public_key();
$resource = openssl_pkey_get_public($publicKey); if (!is_resource($resource)) {
return '';
} $encrypted = "";
openssl_public_encrypt($string, $encrypted, $resource); return $encrypted;
}

2、私钥解密

/**
* 私钥解密
*/
function rsa_decrypt($string) {
$privateKey = get_private_key();
$resource = openssl_pkey_get_private($privateKey); if (!is_resource($resource)) {
return '';
} $decrypted = ''; try {
openssl_private_decrypt($string, $decrypted, $resource); return $decrypted;
} catch (Exception $e) {
return '';
}
}

第四步:测试结果

简单写一个方法进行测试

    /**
* 测试RSA加密解密
*/
public function testEncode(){
$data = 'hello world!';
var_dump('加密前的数据:'.$data);
$encodeData = rsa_encrypt($data);
var_dump('公钥加密后的数据:'.$encodeData);
$decodeData = rsa_decrypt($encodeData);
var_dump('私钥解密后的数据:'.$decodeData);
}

测试结果如下:

从上面结果可以看到原始数据【hello world!】解密后也是【hello world!】,说明使用RSA加解密成功,但是加密后的结果中有乱码,这一问题的解决方式就是在加密和解密过程中使用base64编码。

第五步:解决加密乱码问题

1、公钥加密(加密结果进行base64编码)

 /**
* 公钥加密
*/
function rsa_encrypt($string) {
$publicKey = get_public_key();
$resource = openssl_pkey_get_public($publicKey); if (!is_resource($resource)) {
return '';
} $encrypted = "";
openssl_public_encrypt($string, $encrypted, $resource); return base64_encode($encrypted);
}

注:上面的第15行中对加密结果进行base64编码。

2、私钥解密(解密之前对加密数据进行base64解码)

 /**
* 私钥解密
*/
function rsa_decrypt($string) {
$privateKey = get_private_key();
$resource = openssl_pkey_get_private($privateKey); if (!is_resource($resource)) {
return '';
} $decrypted = ''; try {
openssl_private_decrypt(base64_decode($string), $decrypted, $resource); return $decrypted;
} catch (Exception $e) {
return '';
}
}

注:上面的第15行中,在解密之前对加密数据进行base64解码

3、查看优化后的结果

以上就是用PHP实现的服务端加解密全部过程,需要注意以下几点:

1、  在linux中生成密钥文件之前需要安装openssl库

2、  为解决加密数据出现的乱码问题,需要对加密后的数据进行base64编码

三、B/S模式下的rsa加密

1、前端加密库

PHP端的加解密,可用在第三方跟平台之前的传输数据,但是如果是前端传到后端呢?我们知道前端是采用JavaScript处理业务逻辑,所以当用户密码等数据传到后台服务器之前需要用JavaScript进行加密,假设后台语言是PHP,那么这就涉及加解密一致性的问题,相当于两种语言结合实现rsa非对称加解密过程。而JavaScript已经有了一个加密库jsencrypt.js。

2、jsencrypt.js库的使用

一般来说,前端加密所用到的密钥(公钥或私钥)都是服务器传过来的,前端只需要负责将原始数据加密后传给后台就可以。这里为了介绍jsencrypt.js库的使用,假设前端已经获取到了公钥和私钥,并使用公钥加密,私钥解密。一般只会获取其中的一个进行前端加密,如果是公钥加密,服务端使用私钥解密;如果是私钥加密,服务端使用公钥解密,这里是为了验证jsencrypt.js的加解密效果获取到公钥和私钥的,不要误解。

①公钥加密

  /* 公钥加密 */
function rsaEncrypt(valueData) {
var PublicKey = $("#txt_rsa_public_key").val();
var encrypt = new JSEncrypt();
encrypt.setPublicKey(PublicKey); var encrypted = encrypt.encrypt(valueData); return encrypted;
}

②私钥解密

  /* 私钥解密 */
function rsaDecrypt(valueData) {
var PrivateKey = $("#txt_rsa_private_key").val();
var decrypt = new JSEncrypt();
decrypt.setPrivateKey(PrivateKey); var decrypted = decrypt.decrypt(valueData); return decrypted;
}

③测试方法

  /* 测试加解密 */
function testRsa(){
var data = "hello world!";
console.info("加密前的数据:"+data);
var encodeData = rsaEncrypt(data);
console.info("使用公钥加密后的数据:"+encodeData);
var decodeData = rsaDecrypt(encodeData);
console.info("使用私钥解密后的数据:"+decodeData);
}

④测试结果

根据上面的示例,可以总结用JS实现ras加解密的过程为:

1、  获取JSEncrypt对象。(加密解密都使用同一个实例)

2、  给JSEncrypt对象设置私钥/公钥

3、  调用对象的加密解密方法

由此可以看出,前端加密不需要设置base64编码解码的过程。

四、web登录过程中RSA的运用

通过以上介绍,知道了前后端怎么使用非对称加密算法RSA进行加密解密的过程,可以利用这两部分内容实现web登录过程中对密码的加密,具体的实现过程这里不再赘述,这里只介绍一下流程:

1、在你所用的web服务器(Apache、Tomcat等)指定目录下生成私钥文件;

2、在相同目录下利用私钥文件生成公钥文件;

3、在服务端(代码中)生成公钥和私钥;

4、客户端(WEB前端)从服务端获取公钥;

5、将密码等敏感信息使用公钥加密后传给后台(ajax方式);

6、服务端获取到加密数据后使用自己的私钥进行解密;

以上就是加解密的完整过程,至于其他的密码是否正确之类的验证,就是其他的业务逻辑了。

本次服务端使用PHP,下次介绍服务端Java的方式。

RSA加密算法在WEB中的应用的更多相关文章

  1. RSA加密算法及其与SpringMVC集成

    如有不足,敬请各位提出批评,定会改正.THX! 本文介绍的是RSA加密算法+Spring Security在SpringMVC中的集成使用. Spring Security是什么? 引用: Sprin ...

  2. SpringMVC集成RSA加密算法

    技术交流群: 233513714 本文介绍的是RSA加密算法+Spring Security在SpringMVC中的集成使用. Spring Security是什么? 引用: Spring Secur ...

  3. RSA加密算法的简单案例

    RSA加密算法是目前最有影响力的公钥加密算法,它能够抵抗到目前为止已知的绝大多数密码攻击. 那关于RSA加密算法有哪些应用呢?以下举一个数据库身份验证的案例. 在使用数据集进行身份认证时,密码存在数据 ...

  4. RSA加密算法的java实现

    package rsa; import java.security.*;import java.security.interfaces.*;import javax.crypto.*; public ...

  5. 用实例讲解RSA加密算法(精)

    RSA是第一个比较完善的公开密钥算法,它既能用于加密,也能用于数字签名.RSA以它的三个发明者Ron Rivest, Adi Shamir, Leonard Adleman的名字首字母命名,这个算法经 ...

  6. 关于RSA加密算法的长度限制问题

    RSA是常用的非对称加密算法.近来有学生在项目中使用System.Security类库中的RSA加密算法时,出现了“不正确的长度”,这实际上是因为待加密的数据超长所致..net Framework中提 ...

  7. RSA加密算法的加密与解密

    转发原文链接:RSA加密算法加密与解密过程解析 1.加密算法概述 加密算法根据内容是否可以还原分为可逆加密和非可逆加密. 可逆加密根据其加密解密是否使用的同一个密钥而可以分为对称加密和非对称加密. 所 ...

  8. 【python网络编程】使用rsa加密算法模块模拟登录新浪微博

    一.基础知识 http://blog.csdn.net/pi9nc/article/details/9734437 二.模拟登录 因为上学期参加了一个大数据比赛,需要抓取数据,所以就想着写个爬虫抓取新 ...

  9. 轻松学习RSA加密算法原理

    转自:http://blog.csdn.net/sunmenggmail/article/details/11994013 http://blog.csdn.net/q376420785/articl ...

随机推荐

  1. FHS 文件层次标准

    FHS:文件层次标准 操作系统自身运行使用的 /bin: 存放可执行的二进制程序,管理员和普通用户都可以使用 /sbin:管理员才能执行的命令 运行正常功能的程序存放位置 /usr/bin /usr/ ...

  2. 2019-8-31-dotnet-获取程序所在路径的方法

    title author date CreateTime categories dotnet 获取程序所在路径的方法 lindexi 2019-08-31 16:55:58 +0800 2019-03 ...

  3. tensorboard在Mac OS X系统环境下如何启动

    再次必须写一篇博客,一次来说明这打开tensorboard的艰难之路,遇到了好多错误,真的是走了好多弯路,最后还是解决了 一开始总是报错,不知道是为什么,其实还是自己没有看懂原理,就冲动的开始招呼画瓢 ...

  4. android-启动另外一个Activity

    启动另外一个Activity 在完成了上一节课的学习后,我们已经创建了一个带有text输入框和一个button的app. 在本课中,我们将在MainActivity类中添加SendButton的单击响 ...

  5. android 遍历控件

    做个笔记 androuid 遍历一个 view 下面的子view // 保存 btnSaveRout.setOnClickListener(new OnClickListener() { @Overr ...

  6. 制作windows10系统启动U盘,从零开始。

    1.打开百度,搜索windows下载,选个这个点击进去. 2.会看到下图,然后点击立即下载工具按钮. 3.接下来由于网络的原因,可能需要漫长的等待.会下载一个MediaCreationTool1903 ...

  7. Codeforces 548E Mike ans Foam (与质数相关的容斥多半会用到莫比乌斯函数)

    题面 链接:CF548E Description Mike is a bartender at Rico's bar. At Rico's, they put beer glasses in a sp ...

  8. Python-线程(2)

    目录 GIL全局解释器锁 GIL 与 Lock 多进程 VS 多线程 死锁现象 递归锁 信号量 Semaphore 线程队列 GIL全局解释器锁 在Cpython解释器中,同一个进程下开启的多线程,同 ...

  9. 上海第三产业增加值 占比GDP首破七成

    上海第三产业增加值 占比GDP首破七成 2016年08月16日08:10  来源:新闻晨报 分享到:     不久前结束的ChinaJoy上,一家名为HYPEREAL的VR公司展台前,体验者的热情程度 ...

  10. python基础-基础知识考试_day5 (包括:函数_递归等知识)

    老男孩 Python 基础知识练习(三) 1.列举布尔值为 False 的值空,None,0, False, '', [], {}, () 2.写函数:根据范围获取其中 3 和 7 整除的所有数的和, ...