php自动签发,生成双向验证证书
效果:
代码:
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配置:
本文来自博客园,作者:河北大学-徐小波,转载请注明原文链接:https://www.cnblogs.com/xuxiaobo/p/17045832.html

【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步