效果:

徐小波 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');
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>

 

执行后结果:

徐小波 xuxiaobo.com

 

 

nginx配置:

徐小波 xuxiaobo.com