php自动签发,生成双向验证证书
效果:
代码:
<?php header("Content-type:text/html;charset=utf-8"); error_reporting(E_ALL); ini_set('display_errors', 1); ini_set('memory_limit', '-1'); set_time_limit(0); session_start(); //需要手动去签证书,ca根证书的common name不能和client,server的common name相同 //openssl verify -CAfile ca.crt client.crt //openssl verify -CAfile ca.crt server.crt $domain = !empty($_GET['domain']) ? $_GET['domain'] : 'xuxiaobo.com'; $days = 365 * 10; $subj1 = ""; $subj2 = ""; $subj3 = ""; $openssl = "openssl"; //$cnf = ""; //$subj1 = " -subj \"/C=CN/ST=Beijing/L=Beijing/OU=/O=/AU=CN/Some-State=China/CN={$domain}\""; //$subj2 = " -subj \"/C=CN/ST=Beijing/L=Beijing/CN={$domain}\""; //$subj3 = " -subj \"/C=CN/ST=Beijing/L=Beijing/CN=com\""; //$openssl = "D:/software/OpenSSL-Win64/bin/openssl"; $cnf = " -config D:/software/nginx-1.21.6/conf/ssl/openssl.cnf"; //1.1. 生成一个 CA 私钥: ca.key $input = "{$openssl} genrsa -out ca.key 4096"; echo "{$input}\n"; $res = runCmd($input); print_r($res); echo "\n\n"; //1.2. 生成一个 CA 数字证书请求 $input = "{$openssl} req -new -out ca.csr -key ca.key {$subj3} {$cnf}"; echo "{$input}\n"; $res = runCmd($input, ['CN', 'Beijing', 'Beijing', 'TDZX', 'YFB', 'com', '', '', '']); print_r($res); echo "\n\n"; //1.3. 生成一个 CA 的数字证书: ca.crt(Common Name 随意填写;其它可以填”.”) $input = "{$openssl} x509 -req -in ca.csr -out ca.crt -signkey ca.key -CAcreateserial -days {$days}"; echo "{$input}\n"; $res = runCmd($input); print_r($res); echo "\n\n"; //2.1. 生成 server 端的私钥: server.key $input = "{$openssl} genrsa -out server.key 4096"; echo "{$input}\n"; $res = runCmd($input); print_r($res); echo "\n\n"; //2.2. 生成 server 端数字证书请求: server.csr(Common Name填写访问服务器时域名,配置nginx时用到,不能与CA的相同 其它填写”.”) $input = "{$openssl} req -new -out server.csr -key server.key {$subj2} {$cnf}"; echo "{$input}\n"; $res = runCmd($input, ['CN', 'Beijing', 'Beijing', 'TDZX', 'YFB', 'xuxiaobo.com', '', '', '']); print_r($res); echo "\n\n"; //2.3. 用 CA 私钥签发 server 的数字证书: server.crt $input = "{$openssl} x509 -req -in server.csr -out server.crt -signkey server.key -CA ca.crt -CAkey ca.key -CAcreateserial -days {$days}"; echo "{$input}\n"; $res = runCmd($input); print_r($res); echo "\n\n"; //3.1. 生成客户端的私钥与证书: client.key $input = "{$openssl} genrsa -out client.key 4096"; echo "{$input}\n"; $res = runCmd($input); print_r($res); echo "\n\n"; //3.2. 生成 client 端数字证书请求: client.csr(Common Name填写访问服务器时域名,配置nginx时用到,不能与CA的相同 其它填写”.”) $input = "{$openssl} req -new -out client.csr -key client.key {$subj2} {$cnf}"; echo "{$input}\n"; $res = runCmd($input, ['CN', 'Beijing', 'Beijing', 'TDZX', 'YFB', 'xuxiaobo.com', '', '', '']); print_r($res); echo "\n\n"; //3.3. 用 CA 私钥签发 client 的数字证书: client.crt $input = "{$openssl} x509 -req -in client.csr -out client.crt -signkey client.key -CA ca.crt -CAkey ca.key -CAcreateserial -days {$days}"; echo "{$input}\n"; $res = runCmd($input); print_r($res); echo "\n\n"; //3.4. 生成p12格式客户端证书 //{$openssl} pkcs12 -export -clcerts -in client.crt -inkey client.key -out client.p12 -passout pass:123456 $input = "{$openssl} pkcs12 -export -clcerts -in client.crt -inkey client.key -out client.p12 -passout pass:"; echo "{$input}\n"; $res = runCmd($input); print_r($res); echo "\n\n"; function runCmd($input, $params = []) { $pipes = []; $descriptorspec = array( 0 => array("pipe", "r"), // stdin 1 => array("pipe", "w"), // stdout 2 => array("pipe", "w") // stderr ); // $proc为false,表明命令执行失败 $flag = proc_open($input, $descriptorspec, $pipes, null, null); if ($flag == false) {} else{ if(!empty($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, ]; if($output['retval'] == 0){ return $output; } else{ exit; } } /** * 输出 */ function printrs($str) { return iconv('gbk', 'utf-8//IGNORE', $str); }
执行过程:
D:\workspace\wwwroot82\ssl>php openssl2.php openssl genrsa -out ca.key 4096 Array ( [stdin] => [stdout] => [stderr] => Generating RSA private key, 4096 bit long modulus (2 primes) ........................................................................++++ ..........................++++ e is 65537 (0x010001) [retval] => 0 ) openssl req -new -out ca.csr -key ca.key -config D:/software/nginx-1.21.6/conf/ssl/openssl.cnf Array ( [stdin] => [stdout] => [stderr] => Can't load ./.rnd into RNG 11352:error:2406F079:random number generator:RAND_load_file:Cannot open file:crypto/rand/randfile.c:98:Filename=./.rnd 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 ) openssl x509 -req -in ca.csr -out ca.crt -signkey ca.key -CAcreateserial -days 3650 Array ( [stdin] => [stdout] => [stderr] => Signature ok subject=C = CN, ST = Beijing, L = Beijing, O = TDZX, OU = YFB, CN = com Getting Private key [retval] => 0 ) openssl genrsa -out server.key 4096 Array ( [stdin] => [stdout] => [stderr] => Generating RSA private key, 4096 bit long modulus (2 primes) .............................................................................................++++ .......................................................................................++++ e is 65537 (0x010001) [retval] => 0 ) openssl req -new -out server.csr -key server.key -config D:/software/nginx-1.21.6/conf/ssl/openssl.cnf 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 ) openssl x509 -req -in server.csr -out server.crt -signkey server.key -CA ca.crt -CAkey ca.key -CAcreateserial -days 3650 Array ( [stdin] => [stdout] => [stderr] => Signature ok subject=C = CN, ST = Beijing, L = Beijing, O = TDZX, OU = YFB, CN = xuxiaobo.com Getting Private key Getting CA Private Key [retval] => 0 ) openssl genrsa -out client.key 4096 Array ( [stdin] => [stdout] => [stderr] => Generating RSA private key, 4096 bit long modulus (2 primes) ........................................................................................++++ ................................................................................++++ e is 65537 (0x010001) [retval] => 0 ) openssl req -new -out client.csr -key client.key -config D:/software/nginx-1.21.6/conf/ssl/openssl.cnf 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 ) openssl x509 -req -in client.csr -out client.crt -signkey client.key -CA ca.crt -CAkey ca.key -CAcreateserial -days 3650 Array ( [stdin] => [stdout] => [stderr] => Signature ok subject=C = CN, ST = Beijing, L = Beijing, O = TDZX, OU = YFB, CN = xuxiaobo.com Getting Private key Getting CA Private Key [retval] => 0 ) openssl pkcs12 -export -clcerts -in client.crt -inkey client.key -out client.p12 -passout pass: Array ( [stdin] => [stdout] => [stderr] => [retval] => 0 ) D:\workspace\wwwroot82\ssl>
执行后结果:
nginx配置:
本文来自博客园,作者:河北大学-徐小波,转载请注明原文链接:https://www.cnblogs.com/xuxiaobo/p/17045832.html