1.Http接口安全概述:
1.1、Http接口是互联网各系统之间对接的重要方式之一,使用http接口,开发和调用都很方便,也是被大量采用的方式,它可以让不同系统之间实现数据的交换和共享,但由于http接口开放在互联网上,那么我们就需要有一定的安全措施来保证不能是随随便便就可以调用;
1.2、目前国内互联网公司主要采用两种做法实现接口的安全:
一种是以支付宝等支付公司为代表的私钥公钥签名验证机制;
一种是大量互联网企业都常采用的参数签名验证机制;
2. Http接口安全演进:
2.1.完全开放的接口(完全开放)
2.2.接口参数签名(基本安全)
2.3.接口参数签名+时效性验证(更加安全)
2.4.接口参数私钥签名公钥验签(固若金汤)
2.5.接口参数签名+Https(金钟罩)
2.6.口参数私钥签名公钥验签+Https(金钟罩)
总之:安全是相对的,只有相对的安全,没有绝对的安全!
3.Http接口安全设计及应用
3.1 接口参数私钥签名公钥验签
先来看看私钥+公钥的安全模式,这是一种更为安全的方式,它通过私钥和公钥实现接口的安全,目前互联网中主要是以支付宝
为代表的公司采用这种机制;(有很多开放平台也是采用这种机制) . 具体业务流所示:
该签名是通过4个秘钥来实现的,分别是:
客户端应用私钥 , 客户端公钥 , 服务端应用私钥 , 服务端公钥.
私钥都是用来生成签名的,公钥都是用来解密的,客户端的公钥解密客户端的私钥生成的签名,服务端的公钥解密服务端的私钥生
成的签名,相信这样解释应该会比较好理解的.
好了,下面就来看看是如何具体操作的,我的具体操作步骤:
首先,4把密钥都是通过OpenSSL工具生成,你需要先获得这个工具:官方网站:https://www.openssl.org/
介绍一下这个工具吧,OpenSSL 是一个开源的安全套接字层密码库,囊括主要的密码算法、常用的密钥和证书封装管理功能及SSL协议,并提供丰富的应用程序测试或其它目的使用;OpenSSL整个软件包大概可以分成三个主要的功能部分:SSL协议库、应用程序以及密码算法库;
3.1.1确保Linux已经安装openssl :
使用命令检查Linux是否已经安装openssl:yum list installed | grep openssl
如果没有安装,则执行命令进行安装:yum install openssl openssl-devel -y
3.1.2创建秘钥生成的目的地(文件夹):
ps : 我是在根目录中的soft文件夹下创建的
mkdir server , mkdir client 先创建这两个文件,然后Linux会默认将生成的秘钥放入其中.
3.1.3 生成秘钥
进入server文件,输入openssl 进入Openssl命令行;
使用openssl生成私钥,执行如下命令:
genrsa -out rsa_private_key.pem 2048
注意一点Java开发者需要将私钥转换成PKCS8格式,其他语言不用这一步操作,执行如下命令:
pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -nocrypt -out rsa_private_key_pkcs8.pem
使用openssl生成公钥,执行如下命令:
rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem
退出openssl命令行:exit
经过以上步骤,我们可以在当前目录中(server)看到三个文件:
rsa_private_key.pem(RSA私钥)
rsa_private_key_pkcs8.pem(pkcs8格式RSA私钥)(我们java要使用的私钥是这一个)
rsa_public_key.pem(对应RSA公钥)
client端的秘钥与server端的秘钥生成一样,这里就不叙述了,想体验的朋友自己按照上一步操作再做一遍即可.
公钥加密
function rsaEncrypt($content,$public_key_path){
$pubKey = file\_get\_contents($public_key_path);
$res = openssl\_get\_publickey($pubKey);
//把需要加密的内容,按128位拆开解密
$result = '';
for($i = 0; $i < strlen($content)/128; $i++ ) {
$data = substr($content, $i * 128, 128);
openssl_public_encrypt ($data, $encrypt, $res);
$result .= $encrypt;
}
$result = base64\_encode($result);
openssl_free_key($res);
return $result;
}
私钥解密
function rsaDecrypt($content,$private_key_path){
$priKey = file\_get\_contents($private_key_path);
$res = openssl\_get\_privatekey($priKey);
//用base64将内容还原成二进制
$content = base64\_decode($content);
//把需要解密的内容,按128位拆开解密
$result = '';
for($i = 0; $i < strlen($content)/128; $i++ ) {
$data = substr($content, $i * 128, 128);
openssl_private_decrypt($data, $decrypt, $res);
$result .= $decrypt;
}
openssl_free_key($res);
return $result;
}
数字签名
function rsaSign($content,$public_key_path){
$pubKey = file\_get\_contents($private_key_path);
$res = openssl\_get\_privatekey($pubKey);
//把需要加密的内容,按128位拆开解密
$result = '';
for ($i = 0; $i < strlen($content) / 128; $i++) {
$data = substr($content, $i * 128, 128);
openssl_sign($data, $encrypt, $res);
$result .= $encrypt;
}
$result = base64\_encode($result);
openssl_free_key($res);
return $result;
}
验证数字签名
function rsaVerify($data,$public_key_path,$sign){
$pubKey = file\_get\_contents($public_key_path);
$res = openssl\_get\_publickey($pubKey);
$result = (bool)openssl\_verify($data, base64_decode($sign), $res);
openssl_free_key($res);
return $result;
}
PHP中调用
header("Content-type:text/html;charset='utf-8");
define("PRIVATE_KEY",__DIR__."/key/rsa_private_key.pem");
define("PUBLIC_KEY",__DIR__."/key/rsa_public_key.pem");
$msg = "My love is coincidence.";
$rsa = new Rsa(); //rsa加密演示
$encrypt = $rsa->rsaEncrypt($msg,PUBLIC_KEY); // 通过公钥加密
//rsa解密演示
$decrypt = $rsa->rsaDecrypt($encrypt,PRIVATE_KEY); // 通过私钥解密
//rsa生成数字签名演示
$sign = $rsa->rsaSign($msg,PRIVATE_KEY); // 通过私钥生成数字签名
//rsa验证数字签名演示
$verify = $rsa->rsaVerify($msg,PUBLIC\_KEY,$sign); // 通过公钥验证数字签名
var_dump($verify);
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。