AcmePHP 生成 SSL 证书

之前写过一篇文章(CentOS6给网站开通免费https),使用certbot配置Let’s Encrypt免费证书,该工具要求Python版本≥2.7。CentOS6服务器默认Python版本过低,所以尝试仅依赖PHP的方式申请证书,以下为操作记录。 文中域名example.com为示例,需替换为自己的域名。

准备Acme PHP

这是PHP编写的SSL证书申请工具,PHP需要开启curl和openssl扩展。文档地址:https://acmephp.github.io/documentation/getting-started/1-installation.html 仅下载phar和pubkey两个文件即可完成安装。

cd ~
php -r "copy('[https://github.com/acmephp/acmephp/releases/download/1.0.1/acmephp.phar](https://github.com/acmephp/acmephp/releases/download/1.0.1/acmephp.phar)', 'acmephp.phar');"
php -r "copy('[https://github.com/acmephp/acmephp/releases/download/1.0.1/acmephp.phar.pubkey](https://github.com/acmephp/acmephp/releases/download/1.0.1/acmephp.phar.pubkey)', 'acmephp.phar.pubkey');"
php acmephp.phar --version

申请证书

可以通过yml配置文件申请,下面是手动申请证书步骤。

注册邮箱

php acmephp.phar register xxx@example.com

注意:Windows下此处可能会报错

  1. OpenSSL key creation failed during generation with error: error:02001003:system library:fopen:No such process;
  2. cURL error 60: SSL certificate problem: unable to get local issuer certificate (see [http://curl.haxx.se/libcurl/c/libcurl-errors.html](http://curl.haxx.se/libcurl/c/libcurl-errors.html)); 解决办法参考:AcmePhpSslExceptionKeyPairGenerationException on register #69

授权域名

php acmephp.phar auth example.com

成功后提示创建验证文件:[http://example.com/.well-known/acme-challenge/xxxx](http://example.com/.well-known/acme-challenge/xxxx),文件内容为输出的一串字符。

提示:Windows不能直接右键创建.开头目录,可使用dos命令或PHP脚本创建。

验证域名

php acmephp.phar check -s http example.com

验证成功,即可获取证书。

获取证书

php acmephp.phar request example.com

证书默认存放路径:~/.acmephp/master/certs/example.com,public目录为公钥证书,private目录为私钥。 Nginx等web服务可直接使用pem证书;IIS需要.pfx格式证书,下面是PHP转换代码:

<?php
// 证书文件和私钥文件
$cert = '~/.acmephp/master/certs/example.com/public/cert.pem';
$key = '~/.acmephp/master/certs/example.com/private/key.private.pem';
// 获取证书内容
$x509 = openssl_x509_read(file_get_contents($cert));
// 获取私钥内容
$private_key = openssl_get_privatekey(file_get_contents($key));
// 转为pfx文件,123456为pfx证书密码
$res = openssl_pkcs12_export($x509, $out, $private_key, '123456', array(
    // 证书名称
    'friendly_name' => 'example.com'
));

if ($res) {
    // 保存pfx文件
    file_put_contents('ssl/cert.pfx', $out);
}

查看证书状态

php acmephp.phar status
+-----------------+----------------------------+---------------------+---------------------+----------------+
| Domain          | Issuer                     | Valid from          | Valid to            | Needs renewal? |
+-----------------+----------------------------+---------------------+---------------------+----------------+
| example.com     | Let's Encrypt Authority X3 | 2019-11-27 07:28:36 | 2020-02-25 07:28:36 | No             |
+-----------------+----------------------------+---------------------+---------------------+----------------+

The End!