PHP使用非对称加密算法(RSA)

Posted by Chen Blog on June 29, 2018

本来以为非对称加密算法很简单。几句代码就搞定了。结果搞了我差不多一个下午的时间,网上的很多文章没遇到的问题被我遇到了。在网上找了半天还没找到解决的办法。查来查去。终于是搞定了。

说明

本来以为非对称加密算法很简单。几句代码就搞定了。结果搞了我差不多一个下午的时间,网上的很多文章没遇到的问题被我遇到了。在网上找了半天还没找到解决的办法。查来查去。终于是搞定了。 主要还是创建秘钥的时候。那个OpenSSL的cnf那个文件。 还需要打开php的php_openssl扩展。 php.ini 搜索php_openssl 把前面的分号去掉 extension=php_openssl.dll

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
<?php

/**
 * 为了方便操作非对称加密的算法。
 * Class Rsa
 * @author chen <935938143@qq.com>
 */
class Rsa{
    /**
     * @var array 创建秘钥时需要的配置
     * 格式如下:
     * array(
     *      'config'        => 'D:\phpStudy\Apache\conf\openssl.cnf',    //openssl.cnf的路径。有些电脑不用配置。90%是用配置的
     *      "digest_alg"    => "sha512",
     *      "private_key_bits" => 4096,
     *      "private_key_type" => OPENSSL_KEYTYPE_RSA,
     *
     * );
     *
     */
    private $config = array();

    public function __construct($config=array()){
        $this->config = $config;
    }

    /**
     * 新建一个秘钥对
     * @param string $key 生成秘钥的密码.
     * @return array array('private_key'=>'','public_key'=>'')
     */
    public function create_keypair($key = null){
        // 创建新的密钥对
        $res=openssl_pkey_new($this->config);
        // 获取私钥
        openssl_pkey_export($res, $privkey,$key,$this->config);

        // 解析这个秘钥资源
        $pubkey = openssl_pkey_get_details($res);
        // 得到公钥
        $pubkey = $pubkey["key"];

        // 得到之后。最好是用base64_encode编译一下。
        return array('private_key'=>$privkey,'public_key'=>$pubkey);
    }


    /**
     * 使用私钥将数据加密
     * @param $data string 一个字符串类型的数据
     * @param $private_key string 私钥
     * @param $key string 创建秘钥时你设置的密码
     * @return string 返回加密后的数据
     */
    public function private_encrypt($data,$private_key,$key=null){
        $bool = openssl_private_encrypt($data,$crypted_data,openssl_pkey_get_private($private_key,$key));
        return $bool ? $crypted_data : $bool;
    }

    /**
     * 使用公钥解密
     * @param $data string 用私钥加密后的数据
     * @param $public_key string 公钥
     * @return string 返回解析出来的数据
     */
    public function public_decrypt($data,$public_key){
        $bool = openssl_public_decrypt($data,$decrypted_data,$public_key);
        return $bool ? $decrypted_data : $bool;
    }

    /**
     * 使用公钥将数据加密
     * @param $data string 需要加密的数据
     * @param $public_key string 公钥
     * @return string 加密后的数据
     */
    public function public_encrypt($data,$public_key){
        $bool = openssl_public_encrypt($data,$enctypted_data,$public_key);
        return $bool ? $enctypted_data : $bool;
    }

    /**
     * 使用私钥加密
     * @param $data string 公钥加密数据
     * @param $private_key string 私钥
     * @param null $key 创建秘钥时你设置的密码
     * @return string 返回解密后的数据
     */
    public function private_decrypt($data,$private_key,$key=null){
        $bool = openssl_private_decrypt($data,$decrypted_data,openssl_pkey_get_private($private_key,$key));
        return $bool ? $decrypted_data : $bool;
    }
}

//下面是例子
$config = array(
    'config'        => 'D:\phpStudy\Apache\conf\openssl.cnf',    //openssl.cnf的路径。有些电脑不用配置。90%是用配置的
);

$rsa = new Rsa($config);
$test = $rsa->create_keypair('test');
$private_str =  $rsa->private_encrypt('hello',$test['private_key'],'123');
echo $rsa->public_decrypt($private_str,$test['public_key']);
echo "\n";
$public_str = $rsa->public_encrypt('456',$test['public_key']);
echo $rsa->private_decrypt($public_str,$test['private_key'],'123');


参考网站

如果哪里有写的不好的地方。请多指教