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

效果:

徐小波 xuxiaobo.com

 

 

徐小波 xuxiaobo.com

 

 

 

徐小波 xuxiaobo.com

 

 

 

代码:

<?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);
}

  

执行过程:

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 @ 2023-01-12 10:54  河北大学-徐小波  阅读(67)  评论(0编辑  收藏  举报