Welcome to 徐小波’s blog.|

河北大学-徐小波

园龄:2年2个月粉丝:1关注:4

php自动签发,生成双向验证证书

效果:

徐小波 xuxiaobo.com

 

 

徐小波 xuxiaobo.com

 

 

 

徐小波 xuxiaobo.com

 

 

 

代码:

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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
<?php
header("Content-type:text/html;charset=utf-8");
error_reporting(E_ALL);
ini_set('display_errors', 1);
ini_set('memory_limit', '-1');
date_default_timezone_set('Asia/Shanghai');
set_time_limit(0);
session_start();
 
 
//需要手动去签证书,ca根证书的common name不能和client,server的common name相同
//openssl verify ca.crt
//openssl verify -CAfile ca.crt server.crt
//openssl verify -CAfile ca.crt client.crt
$domain = !empty($_GET['domain']) ? $_GET['domain'] : 'xuxiaobo.com';
$days = 365 * 100;
$strparams = false;
$subjsc = " -subj \"/C=Cn/ST=Beijing/L=Beijing/CN={$domain}\"";
$subjca = " -subj \"/C=Cn/ST=Beijing/L=Beijing/CN=com\"";
 
if(PHP_OS == 'WINNT'){
    $openssl = "D:/software/OpenSSL-Win64/bin/openssl.exe";
    $cnf = "D:/software/nginx-1.21.6/conf/ssl/openssl.cnf";
} else {
    $openssl = "/usr/bin/openssl";
    $cnf = "";
}
 
//1.1. 生成一个 CA 私钥: ca.key
$input = "{$openssl} genrsa -out ca.key 4096";
runCmd($input);
 
//1.2. 生成一个 CA 数字证书请求
$input = "{$openssl} req -new -key ca.key -out ca.csr";
$params = $strparams ? $subjca : ['CN', 'Beijing', 'Beijing', 'TDZX', 'YFB', 'com', '', '', ''];
runCmd($input, $params, $cnf);
 
//1.3. 生成一个 CA 的数字证书: ca.crt(Common Name 随意填写;其它可以填”.”)
//-CAcreateserial 表示创建CA证书序列号
$input = "{$openssl} x509 -req -in ca.csr -signkey ca.key -out ca.crt -days {$days}";
runCmd($input);
 
//1.4. 生成p12格式ca证书
//{$openssl} pkcs12 -export -clcerts -in ca.crt -inkey ca.key -out ca.p12 -passout pass:123456
$input = "{$openssl} pkcs12 -export -in ca.crt -inkey ca.key -out ca.p12 -passout pass:";
runCmd($input);
 
 
 
//2.1. 生成 server 端的私钥: server.key
$input = "{$openssl} genrsa -out server.key 4096";
runCmd($input);
 
//2.2. 生成 server 端数字证书请求: server.csr(Common Name填写访问服务器时域名,配置nginx时用到,不能与CA的相同 其它填写”.”)
$input = "{$openssl} req -new -key server.key -out server.csr";
$params = $strparams ? $subjsc : ['CN', 'Beijing', 'Beijing', 'TDZX', 'YFB', 'xuxiaobo.com', '', '', ''];
runCmd($input, $params, $cnf);
 
//2.3. 用 CA 私钥签发 server 的数字证书: server.crt
//-CAcreateserial 表示创建CA证书序列号
//openssl x509 -req -days 3650 -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt
//$input = "{$openssl} x509 -req -in server.csr -signkey server.key -CA ca.crt -CAkey ca.key -out server.crt -CAcreateserial -days {$days}";
$input = "{$openssl} x509 -req -in server.csr -CA ca.crt -CAkey ca.key -out server.crt -CAcreateserial -days {$days}";
runCmd($input);
 
//2.4. 生成p12格式服务端证书
//{$openssl} pkcs12 -export -clcerts -in server.crt -inkey server.key -out server.p12 -passout pass:123456
$input = "{$openssl} pkcs12 -export -in server.crt -inkey server.key -out server.p12 -passout pass:";
runCmd($input);
 
 
 
//3.1. 生成客户端的私钥与证书: client.key
$input = "{$openssl} genrsa -out client.key 4096";
runCmd($input);
 
//3.2. 生成 client 端数字证书请求: client.csr(Common Name填写访问服务器时域名,配置nginx时用到,不能与CA的相同 其它填写”.”)
$input = "{$openssl} req -new -key client.key -out client.csr";
$params = $strparams ? $subjsc : ['CN', 'Beijing', 'Beijing', 'TDZX', 'YFB', 'xuxiaobo.com', '', '', ''];
runCmd($input, $params, $cnf);
 
//3.3. 用 CA 私钥签发 client 的数字证书: client.crt
//$input = "{$openssl} x509 -req -in client.csr -signkey client.key -CA ca.crt -CAkey ca.key -out client.crt -CAcreateserial -days {$days}";
$input = "{$openssl} x509 -req -in client.csr -CA ca.crt -CAkey ca.key -out client.crt -CAcreateserial -days {$days}";
runCmd($input);
 
//3.4. 生成p12格式客户端证书
//{$openssl} pkcs12 -export -clcerts -in client.crt -inkey client.key -out client.p12 -passout pass:123456
$input = "{$openssl} pkcs12 -export -in client.crt -inkey client.key -out client.p12 -passout pass:";
runCmd($input);
 
 
function runCmd($input, $params = null, $cnf = '')
{
    $myinput = !empty($cnf) ? "{$input} -config {$cnf}" : "{$input}";
    if(!empty($params)){
        if(is_string($params)){
            $myinput = !empty($cnf) ? "{$input} {$params} -config {$cnf}" : "{$input} {$params}";
        }
    }
 
    echo "{$myinput}\n";
    if(!empty($params)){
        if(is_array($params)){
            print_r($params);
            echo "\n\n";
        }
    }
 
    $pipes = [];
    $descriptorspec = array(
        0 => array("pipe", "r"),    // stdin
        1 => array("pipe", "w"),    // stdout
        2 => array("pipe", "w")     // stderr
    );
 
    // $proc为false,表明命令执行失败
    $flag = proc_open($myinput, $descriptorspec, $pipes, null, null);
    if ($flag == false) {}
    else{
        if(!empty($params) && is_array($params)){
            foreach($params as $param){
                fwrite($pipes[0], "{$param}\n");
            }
        }
 
        $stdin = stream_get_contents($pipes[0]);
        fclose($pipes[0]);
 
        $stdout = stream_get_contents($pipes[1]);
        fclose($pipes[1]);
 
        $stderr = stream_get_contents($pipes[2]);
        fclose($pipes[2]);
 
        $status = proc_close($flag);  // 释放proc
    }
 
    $output = [
        'stdin' => printrs($stdin),
        'stdout' => printrs($stdout),
        'stderr' => printrs($stderr),
        'retval' => $status,
    ];
     
    print_r($output);
    echo "\n\n";
 
    if($output['retval'] == 0){
        return $output;
    }
    else{
        exit;
    }
}
 
/**
 * 输出
 */
function printrs($str)
{
    return iconv('gbk', 'utf-8//IGNORE', $str);
}

  

执行过程:

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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
D:/software/OpenSSL-Win64/bin/openssl.exe genrsa -out ca.key 4096
Array
(
    [stdin] =>
    [stdout] =>
    [stderr] =>
    [retval] => 0
)
 
 
D:/software/OpenSSL-Win64/bin/openssl.exe req -new -key ca.key -out ca.csr -config D:/software/nginx-1.21.6/conf/ssl/openssl.cnf
Array
(
    [0] => CN
    [1] => Beijing
    [2] => Beijing
    [3] => TDZX
    [4] => YFB
    [5] => com
    [6] =>
    [7] =>
    [8] =>
)
 
 
Array
(
    [stdin] =>
    [stdout] =>
    [stderr] => You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:State or Province Name (full name) [Some-State]:Locality Name (eg, city) []:Organization Name (eg, company) [Internet Widgits Pty Ltd]:Organizational Unit Name (eg, section) []:Common Name (e.g. server FQDN or YOUR name) []:Email Address []:
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:An optional company name []:
    [retval] => 0
)
 
 
D:/software/OpenSSL-Win64/bin/openssl.exe x509 -req -in ca.csr -signkey ca.key -out ca.crt -days 36500
Array
(
    [stdin] =>
    [stdout] =>
    [stderr] =>
    [retval] => 0
)
 
 
D:/software/OpenSSL-Win64/bin/openssl.exe pkcs12 -export -in ca.crt -inkey ca.key -out ca.p12 -passout pass:
Array
(
    [stdin] =>
    [stdout] =>
    [stderr] =>
    [retval] => 0
)
 
 
D:/software/OpenSSL-Win64/bin/openssl.exe genrsa -out server.key 4096
Array
(
    [stdin] =>
    [stdout] =>
    [stderr] =>
    [retval] => 0
)
 
 
D:/software/OpenSSL-Win64/bin/openssl.exe req -new -key server.key -out server.csr -config D:/software/nginx-1.21.6/conf/ssl/openssl.cnf
Array
(
    [0] => CN
    [1] => Beijing
    [2] => Beijing
    [3] => TDZX
    [4] => YFB
    [5] => xuxiaobo.com
    [6] =>
    [7] =>
    [8] =>
)
 
 
Array
(
    [stdin] =>
    [stdout] =>
    [stderr] => You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:State or Province Name (full name) [Some-State]:Locality Name (eg, city) []:Organization Name (eg, company) [Internet Widgits Pty Ltd]:Organizational Unit Name (eg, section) []:Common Name (e.g. server FQDN or YOUR name) []:Email Address []:
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:An optional company name []:
    [retval] => 0
)
 
 
D:/software/OpenSSL-Win64/bin/openssl.exe x509 -req -in server.csr -CA ca.crt -CAkey ca.key -out server.crt -CAcreateserial -days 36500
Array
(
    [stdin] =>
    [stdout] =>
    [stderr] =>
    [retval] => 0
)
 
 
D:/software/OpenSSL-Win64/bin/openssl.exe pkcs12 -export -in server.crt -inkey server.key -out server.p12 -passout pass:
Array
(
    [stdin] =>
    [stdout] =>
    [stderr] =>
    [retval] => 0
)
 
 
D:/software/OpenSSL-Win64/bin/openssl.exe genrsa -out client.key 4096
Array
(
    [stdin] =>
    [stdout] =>
    [stderr] =>
    [retval] => 0
)
 
 
D:/software/OpenSSL-Win64/bin/openssl.exe req -new -key client.key -out client.csr -config D:/software/nginx-1.21.6/conf/ssl/openssl.cnf
Array
(
    [0] => CN
    [1] => Beijing
    [2] => Beijing
    [3] => TDZX
    [4] => YFB
    [5] => xuxiaobo.com
    [6] =>
    [7] =>
    [8] =>
)
 
 
Array
(
    [stdin] =>
    [stdout] =>
    [stderr] => You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:State or Province Name (full name) [Some-State]:Locality Name (eg, city) []:Organization Name (eg, company) [Internet Widgits Pty Ltd]:Organizational Unit Name (eg, section) []:Common Name (e.g. server FQDN or YOUR name) []:Email Address []:
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:An optional company name []:
    [retval] => 0
)
 
 
D:/software/OpenSSL-Win64/bin/openssl.exe x509 -req -in client.csr -CA ca.crt -CAkey ca.key -out client.crt -CAcreateserial -days 36500
Array
(
    [stdin] =>
    [stdout] =>
    [stderr] =>
    [retval] => 0
)
 
 
D:/software/OpenSSL-Win64/bin/openssl.exe pkcs12 -export -in client.crt -inkey client.key -out client.p12 -passout pass:
Array
(
    [stdin] =>
    [stdout] =>
    [stderr] =>
    [retval] => 0
)

  

执行后结果:

 

 

 

nginx配置:

徐小波 xuxiaobo.com

 

posted @   河北大学-徐小波  阅读(72)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起