直接上代码
PHP需要openssl扩展
<?php
/**
* 使用openssl实现非对称加密
*/
class Rsa
{
/**
* 私钥地址
*/
private $_privKey;
/**
* 公钥地址
*/
private $_pubKey;
/**
* 证书地址
*/
private $_keyPath;
/**
* 初始化
*/
public function __construct($path)
{
if(empty($path) || !is_dir($path)){
throw new Exception('必须设置证书地址');
}
$this->_keyPath = $path;
}
/**
* 创建公钥和私钥
*/
public function createKey()
{
$config = array('config' => 'C:\phpStudy\PHPTutorial\nginx\conf\openssl.cnf');
$r = openssl_pkey_new($config);
openssl_pkey_export($r, $privKey,null,$config);
file_put_contents($this->_keyPath . DIRECTORY_SEPARATOR . 'priv.key', $privKey);
$this->_privKey = openssl_pkey_get_public($privKey);
$rp = openssl_pkey_get_details($r);
$pubKey = $rp['key'];
file_put_contents($this->_keyPath . DIRECTORY_SEPARATOR . 'pub.key', $pubKey);
$this->_pubKey = openssl_pkey_get_public($pubKey);
}
/**
* 获取私钥
*/
public function setupPrivKey()
{
if(is_resource($this->_privKey)){
return true;
}
$file = $this->_keyPath . DIRECTORY_SEPARATOR . 'priv.key';
$prk = file_get_contents($file);
$this->_privKey = openssl_pkey_get_private($prk);
return true;
}
/**
* 获取公钥
*/
public function setupPubKey()
{
if(is_resource($this->_pubKey)){
return true;
}
$file = $this->_keyPath . DIRECTORY_SEPARATOR . 'pub.key';
$puk = file_get_contents($file);
$this->_pubKey = openssl_pkey_get_public($puk);
return true;
}
/**
* 私钥加密
*/
public function privEncrypt($data)
{
if(!is_string($data)){
return null;
}
$this->setupPrivKey();
$r = openssl_private_encrypt($data, $encrypted, $this->_privKey);
if($r){
return base64_encode($encrypted);
}
return null;
}
/**
* 私钥解密
*/
public function privDecrypt($encrypted)
{
if(!is_string($encrypted)){
return null;
}
$this->setupPrivKey();
$encrypted = base64_decode($encrypted);
$r = openssl_private_decrypt($encrypted, $decrypted, $this->_privKey);
if($r){
return $decrypted;
}
return null;
}
/**
* 公钥加密
*/
public function pubEncrypt($data)
{
if(!is_string($data)){
return null;
}
$this->setupPubKey();
$r = openssl_public_encrypt($data, $encrypted, $this->_pubKey);
if($r){
return base64_encode($encrypted);
}
return null;
}
/**
* 公钥解密
*/
public function pubDecrypt($crypted)
{
if(!is_string($crypted)){
return null;
}
$this->setupPubKey();
$crypted = base64_decode($crypted);
$r = openssl_public_decrypt($crypted, $decrypted, $this->_pubKey);
if($r){
return $decrypted;
}
return null;
}
public function __destruct()
{
@ fclose($this->_privKey);
@ fclose($this->_pubKey);
}
}
$rsa = new Rsa('ssl-key');
//$rsa->createKey(); //运行一次 创建公钥和私钥
//公钥加密私钥解密
$pue = $rsa->pubEncrypt('被加密的数据');
$prd = $rsa->privDecrypt($pue);
//私钥加密公钥解密
$pre = $rsa->privEncrypt('被加密的数据');
$pud = $rsa->pubDecrypt($pre);
通过RSA算法我们可以实现API接口的安全认证机制
认证流程
a) 密钥分配:RSA算法通过工具或方法调用生成公钥和私钥(1024bit),请求端使用公钥,服务端使用私钥。
b) 加密方式:请求端通过密钥分配获取公钥,根据RSA加密算法将进行哈希后的明文请求进行公钥加密生成token;服务端通过密钥分配获取私钥,根据RSA解密算法将请求端的token进行私钥解密。
c) 认证方式:在服务端,如果明文请求的哈希值和私钥解密后信息的哈希值是一致的,则认为认证成功,完成授权。
d) 数据传输:RSA加密生成的是乱码,为了传输,将数据进行Base64封装,服务端收到之后进行解封装。
下面配个图,方便理解