PHP 非对称加密实现

10 篇文章 0 订阅

PHP 实现非对称加密逻辑 -实现保护用户数据安全

在日常设计及开发中,为确保数据传输和数据存储的安全,可通过特定的算法,将数据明文加密成复杂的密文。目前主流加密手段大致可分为单向加密和双向加密。

单向加密:通过对数据进行摘要计算生成密文,密文不可逆推还原。算法代表:Base64,MD5,SHA; 

双向加密:与单向加密相反,可以把密文逆推还原成明文,双向加密又分为对称加密和非对称加密。

对称加密:指数据使用者必须拥有相同的密钥才可以进行加密解密,就像彼此约定的一串暗号。算法代表:DES,3DES,AES,IDEA,RC4,RC5;

非对称加密:相对对称加密而言,无需拥有同一组密钥,非对称加密是一种“信息公开的密钥交换协议”。非对称加密需要公开密钥和私有密钥两组密钥,公开密钥和私有密钥是配对起来的,
也就是说使用公开密钥进行数据加密,只有对应的私有密钥才能解密。这两个密钥是数学相关,用某用户密钥加密后的密文,只能使用该用户的加密密钥才能解密。如果知道了其中一个,并
不能计算出另外一个。因此如果公开了一对密钥中的一个,并不会危害到另外一个密钥性质。这里把公开的密钥为公钥,不公开的密钥为私钥。算法代表:RSA,DSA。

非对称加密算法

需要两个密钥:公开密钥(publickey)和私有密钥(privatekey)。
公开密钥与私有密钥是一对,如果用公开密钥对数据进行加密,只有用对应的私有密钥才能解密;
如果用私有密钥对数据进行加密,那么只有用对应的公开密钥才能解密。
因为加密和解密使用的是两个不同的密钥,所以这种算法叫作非对称加密算法。

注意以上的一个点,公钥加密的数据,只有对应的私钥才能解密

在日常使用中是酱紫的:

将私钥private_key.pem用在服务器端,公钥发放给android跟ios等前端

客户端用公钥加密过后,数据只能被拥有唯一私钥的服务器看懂。

代码:

<?php
namespace Classes\Third\Utils;


/**
 * 非对称加密
 * @author	田小涛
 * @date	2019年10月30日
 * @comment 数据安全机制
 *
 */
class RsaUtils
{
    
    //公钥
    private $private;
    //私钥
    private $public;
    //公-私钥存储位置
    private $keyPath;
    private $openssl;
    
    private static $_instance;
    private function __construct()
    {
        $this->keyPath = dirname( dirname( __FILE__ ) ) . DIRECTORY_SEPARATOR . 'rsa';
        $this->openssl = 'D:\Works\phpStudy\PHPTutorial\Apache\conf\openssl.cnf';
        $this->_init();
    }
    public static function getInstance()
    {
        if( null == self::$_instance )
        {
            self::$_instance = new self();
        }
        
        return self::$_instance;
    }
    
    /**
     * 初始化公-私钥
     * @author	 田小涛
     * @datetime 2019年10月30日 下午1:14:01
     * @comment	
     * 
     * @return boolean
     */
    private function _init()
    {
        if( !file_exists( $this->keyPath . DIRECTORY_SEPARATOR . 'private_key.pem'  ) || !file_exists( $this->keyPath . DIRECTORY_SEPARATOR . 'public_key.pem' ) )
        {
            $this->initialization();
        }
        
        return true;
    }
    
    /**
     * 初始化公-私钥
     * @author	 田小涛
     * @datetime 2019年10月30日 下午1:05:59
     * @comment	
     *
     */
    protected function initialization()
    {
        $config = array(
            'digest_alg'        => 'sha512',
            'private_key_bits'  => 2048,
            'private_key_type'  => OPENSSL_KEYTYPE_RSA,
            'config'            => $this->openssl,
        );
        try{
            //创建密钥对
            $res = openssl_pkey_new( $config );
            //生成私钥
            openssl_pkey_export($res, $privkey, null, $config);
            //生成公钥
            $pubKey = openssl_pkey_get_details($res)[ 'key' ];
            file_put_contents( $this->keyPath . DIRECTORY_SEPARATOR . 'private_key.pem', $privkey );
            file_put_contents( $this->keyPath . DIRECTORY_SEPARATOR . 'public_key.pem', $pubKey );
            
            $this->private = openssl_pkey_get_private( $privkey );
            $this->public = openssl_pkey_get_public( $privkey );
        }catch ( \Exception $e ){
            
        }
        
        return true;
    }
    
    
    /**
     * 提取私钥
     * @author	 田小涛
     * @datetime 2019年10月30日 上午11:38:02
     * @comment	
     * 
     * @return resource
     */
    private function _getPrivateKey()
    {
        $strPrivateKey = $this->keyPath . DIRECTORY_SEPARATOR. 'private_key.pem';
        $key = file_get_contents( $strPrivateKey );
        
        return openssl_pkey_get_private( $key );
    }
    
    
    /**
     * 提取公钥
     * @author	 田小涛
     * @datetime 2019年10月30日 上午11:38:15
     * @comment	
     * 
     * @return resource
     */
    private function _getPublicKey()
    {
        $strPublicKey = $this->keyPath . DIRECTORY_SEPARATOR . 'public_key.pem';
        $key = file_get_contents( $strPublicKey );
        
        return openssl_pkey_get_public( $key );     
    }
    
    
    /**
     * 获取公钥
     * @author	 田小涛
     * @datetime 2019年10月30日 上午11:41:31
     * @comment	
     * 
     * @return resource
     */
    public function getPublicKey()
    {
        $this->public =  $this->_getPublicKey();
        
        return $this->public;
    }
    
    /**
     * 获取私钥
     * @author	 田小涛
     * @datetime 2019年10月30日 上午11:41:53
     * @comment	
     * 
     * @return resource
     */
    public function getPrivateKey()
    {
        $this->private =  $this->_getPrivateKey();
        
        return $this->private;
    }
    
    
    /**
     * 私钥加密
     * @author	 田小涛
     * @datetime 2019年10月30日 上午11:43:42
     * @comment	
     * 
     * @param unknown $data
     */
    public function privEncrypt( $data = null )
    {
        if( is_null( $data ) )
        {
            return null;
        }
        if ( ( is_array( $data ) || is_object( $data ) ) && !empty( $data ) ) 
        {
            $data = json_encode( $data );
        }
        
        return openssl_private_encrypt( $data, $encrypted, $this->_getPrivateKey() ) ? base64_encode( $encrypted ) : null; 
    }
    
    /**
     * 公钥加密
     * @author	 田小涛
     * @datetime 2019年10月30日 上午11:43:42
     * @comment	
     * 
     * @param unknown $data
     */
    public function publicEncrypt( $data = null )
    {
        if( is_null( $data ) )
        {
            return null;
        }
        if ( ( is_array( $data ) || is_object( $data ) ) && !empty( $data ) ) 
        {
            $data = json_encode( $data );
        }   
        
        return openssl_public_encrypt( $data, $encrypted, $this->_getPublicKey() ) ? base64_encode( $encrypted ) : null; 
    }
    
    
    /**
     * 私钥解密
     * @author	 田小涛
     * @datetime 2019年10月30日 上午11:47:50
     * @comment	
     * 
     * @param unknown $encrypted
     */
    public function privDecrypt( $encrypted = null )
    {
        if( is_null( $encrypted ) || !is_string( $encrypted ) || strlen( $encrypted ) <= 0 )
        {
            return null;
        }
        
        return ( openssl_private_decrypt( base64_decode( $encrypted ), $decrypted, $this->_getPrivateKey() ) ) ? $decrypted : null;    
    }
    
    /**
     * 公钥解密
     * @author	 田小涛
     * @datetime 2019年10月30日 上午11:47:50
     * @comment	
     * 
     * @param unknown $encrypted
     */
    public function publicDecrypt( $encrypted = null )
    {
        if( is_null( $encrypted ) || !is_string( $encrypted ) || strlen( $encrypted ) <= 0 )
        {
            return null;
        }
        
        return ( openssl_public_decrypt( base64_decode( $encrypted ), $decrypted, $this->_getPublicKey() ) ) ? $decrypted : null;    
    }
    
    
}

调用示例:

$en  = RsaUtils::getInstance();
$data = [ 'id' => 1, 'name' => '张三', 'age' => 12 ];
echo '<pre>';
var_dump( $data );
echo '<pre>';
$encrypt = $en->publicEncrypt( $data );
echo '加密字符串:' . $encrypt . '<br />';
$de = $en->privDecrypt( $encrypt );
    
echo '<pre>';
var_dump( json_decode( $de, true )  );
echo '<pre>';
exit;

**********************

那么该类会在初始化的时候检测公钥/私钥文件是否存在 若不存在则采用重新生成的方式生成

这个时候我们就可以实现每天/固定时间更新公钥/私钥确保更安全的数据传输

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值