最近做APP,由于刚开始开发,所以关于数据传输之间的加密部分还没做。在BOSS的要求下,准备给APP的接口加上RSA加密。先测试一个小demo。
一、使用场景
APP接口数据部分的加密。特别是设计到账号密码,如果是明文传输的话,这是极为危险的一件事,因此我们需要在接口部分进行数据加密。这里选用RSA加密方式,前端进行加密,后端进行解密操作。然后后端再进行一些加密,存入数据库。
二、RSA的概念
1、RSA简介
RSA公钥加密算法是1977年由Ron Rivest、Adi Shamirh和LenAdleman在(美国麻省理工学院)开发的。RSA取名来自开发他们三者的名字。
RSA是目前最有影响力的公钥加密算法,它能够抵抗到目前为止已知的所有密码攻击,已被ISO推荐为公钥数据加密标准。
目前该加密方式广泛用于网上银行、数字签名等场合。
RSA算法基于一个十分简单的数论事实:将两个大素数相乘十分容易,但那时想要对其乘积进行因式分解却极其困难,因此可以将乘积公开作为加密密钥。
2、算法核心
RSA的算法涉及三个参数,n、e1、e2。
其中,n是两个大质数p、q的积,n的二进制表示时所占用的位数,就是所谓的密钥长度。
e1和e2是一对相关的值,e1可以任意取,但要求e1与(p-1)(q-1)互质;再选择e2,要求(e2*e1)mod((p-1)(q-1))=1。
(n,e1),(n,e2)就是密钥对。其中(n,e1)为公钥,(n,e2)为私钥。[1]
RSA加解密的算法完全相同,设A为明文,B为密文,则:A=B^e2 mod n;B=A^e1 mod n;(公钥加密体制中,一般用公钥加密,私钥解密)
e1和e2可以互换使用,即:
A=B^e1 mod n;B=A^e2 mod n;
详细的请去:https://github.com/HaleyLeoZhang/rsa-js-php观看
三、RSA加密的用法。
这里应用的步骤是,前端加密–》后端解密–》解密的数据正确则表示成功
1、前端加密部分
这里先引入封装好的方法,RsaUtil.php,然后再app下新建keys目录,里面存放
我们生成的公钥和私钥。
2、引入JS文件
<script src="http://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
<script src="./js/rsa/js/hlz_rsa.js"></script>
下面的那个hlz_rsa.js是封装好的js文件,作用是对数据进行RSA加密。这个JS文件下载地址:https://github.com/HaleyLeoZhang/rsa-js-php
3、做一个简单的html页面,进行点击提交
4、ajax部分的代码
<script type="text/javascript">
function setStatus(o) {
//alert(1);
var username = $("#username").val();
var csrf_token = $("#csrf_token").val();
//这里的rsa_encode就是我们引入的那个JS文件封装的好的方法。
//直接调用该方法进行加密即可。
//encodeURIComponent这个是框架自带的一个方法。我也不知道有什么用,
//这个方法用不用都可以的
var user = rsa_encode(encodeURIComponent(username));
//alert(user);
$.ajax({
//这个部分是laravel中的csrf_token防护,需要了解的同学请观看我的博客
//地址:http://blog.youkuaiyun.com/ljfphp/article/details/78563297
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
},
url: "{{url('/rsa_post')}}",
type: "post",
dataType: "json",
data: {
"username":user,
"csrf_token": csrf_token
},
success: function(r) {
if (!r.err) {
location.href = "{{url('/test1')}}";
} else {
alert(r.err);
}
}
});
}
</script>
这里的代码是前端部分加密,然后通过ajax方法进行提交
5、php部分接收数据,然后进行解密。解密之后打印,看看数据对不对。
(1)控制器代码
/*
* 测试Post过来的值
* */
public function PostRsa(Request $request){
$username = $request->input('username');
//var_dump($username);
//这里的 self::rsa_decode()就是解密的算法,算是封装好的,直接调用即可
$user_name = self::rsa_decode($username);
//var_dump($user_name);
return view('rsa.rsa_res',['result'=>$user_name]);
}
(2)封装的解密方法
// rsa 解密
private static function rsa_decode($data){
return urldecode(
RsaUtil::privDecrypt(
$data ,
file_get_contents( base_path('keys/rsa_private_key.pem') )
)
);
}
(3)上面封装分方法部分是调用了一个RsaUtil类。具体的代码部分如下:
<?php
namespace App\Helpers;
class RsaUtil {
private static function getPrivateKey($privateKey){
return openssl_pkey_get_private($privateKey);
}
/**
* 私钥加密
*/
public static function privEncrypt($data,$privateKey){
if(!is_string($data)){
return null;
}
return openssl_private_encrypt($data,$encrypted,self::getPrivateKey($privateKey))? base64_encode($encrypted) : null;
}
/**
* 私钥解密
*/
public static function privDecrypt($encrypted,$privateKey)
{
if(!is_string($encrypted)){
return null;
}
return (openssl_private_decrypt(base64_decode($encrypted), $decrypted, self::getPrivateKey($privateKey)))? $decrypted : null;
}
}
6、按照上面的代码走一遍,我们通过打印就会知道自己已经进行RSA加密解密成功了。
在控制器上打印一下,发现传过来的值就是这个。但是在ajax传输过程中,我们是加密方式传输的,不用担心会被别人获取到账号密码等私密数据了。
end