fyrkat/openssl

PHP 内置 openssl_* 函数的类封装

维护者

详细信息

git.sr.ht/~jornane/php-openssl

v2.0.0 2024-09-30 16:12 UTC

This package is auto-updated.

Last update: 2024-09-30 18:41:15 UTC


README

本项目提供围绕 openssl_* 函数的类,以便使使用密钥和证书的工作更加易于接受。它仍在开发中。欢迎提交补丁和错误报告。

要求

  • PHP >=7.1
  • Make
  • (首次设置) 需要互联网连接

使用方法

请确保在您的代码中使用 严格类型

<?php declare(strict_types=1);

自签名

为了制作自签名的 CA,您需要一个密钥。

<?php
$caPrivKey = new PrivateKey( new OpenSSLConfig( OpenSSLConfig::KEY_EC ) );
// Instead of OpenSSLConfig::KEY_EC you could use OpenSSLConfig::KEY_RSA.

从这个密钥我们将制作一个签名请求。

<?php
$caCsr = CSR::generate(
		new DN( ['CN' => 'fyrkat example CA'] ), // Subject
		$caPrivKey // CA key
	);

现在这个请求可以自签名了。

<?php
$caCertificate = $caCsr->sign(
		null, // CA certificate
		$caPrivKey, // CA key
		18250, // Validity in days
		new OpenSSLConfig( OpenSSLConfig::X509_CA ) // EKU
	);
// We need the same $caPrivKey again because self-sign means you sign with your own key.
// OpenSSLConfig::X509_CA means that the resulting certificate is to be used as a CA.
// Other options are OpenSSLConfig::X509_SERVER and OpenSSLConfig::X509_CLIENT.

使用自己的 CA 签名

如果您已经拥有自己的 CA,请导入它。

<?php
// Update these three lines to your own liking.
$caPrivPem = getMyPrivateKeyPemFromSomewhere();
$caPrivPemPassphrase = 'supersecret'; // or null if no passphrase.
$caCertificatePem = getMyPrivateKeyPemFromSomewhere();
$caPrivKey = new PrivateKey( $caPrivPem, $passphrase );
$caCertificate = new X509( $caCertificatePem );

使用您的 CA 签名服务器证书

<?php
$serverPrivKey = new PrivateKey( new OpenSSLConfig( OpenSSLConfig::KEY_EC ) );
// Instead of OpenSSLConfig::KEY_EC you could use OpenSSLConfig::KEY_RSA.
$serverCsr = CSR::generate(
		new DN( ['CN' => 'example.com'] ), // Subject
		$serverPrivKey // Server key
	);
$serverCertificate = $caCsr->sign(
		$caCertificate, // CA certificate
		$caPrivKey, // CA key
		1095, // Validity in days
		new OpenSSLConfig( OpenSSLConfig::X509_SERVER ) // EKU
	);
// Using $caCertificate ensures the resulting certificate is signed by $caCertificate,
// instead of being self-signed.
// OpenSSLConfig::X509_SERVER indicates that this will be a server certificate.

使用您的 CA 签名客户端证书

<?php
$clientPrivKey = new PrivateKey( new OpenSSLConfig( OpenSSLConfig::KEY_EC ) );
$clientCsr = CSR::generate(
		new DN( ['CN' => 'jornane@example.com'] ), // Subject
		$clientPrivKey // Client key
	);
$clientCertificate = $caCsr->sign(
		$caCertificate, // CA certificate
		$caPrivKey, // CA key
		1095, // Validity in days
		new OpenSSLConfig( OpenSSLConfig::X509_CLIENT ) // EKU
	);

检索 PEM 表示形式

包含公钥材料的类具有 __toString() 方法,允许您将其用作字符串。

<?php
echo $serverCertificate; // PEM output

但是,PrivateKey 没有这个功能,以避免意外泄露数据。所有类都有一个获取 PEM 字符串的功能。

<?php
$caCertificatePem = $caCertificate->getX509Pem();
$serverCertificatePem = $serverCertificate->getX509Pem();
$serverPrivKeyPem = $serverPrivKey->getPrivateKeyPem( 'supersecret' );
// Instead of 'supersecret', you can use null if you don't want the output encrypted

// Additionally, you could export just the public key, but it might not be that useful
$pkPem = $serverCertificate->getPublicKey()->getPublicKeyPem();

已知问题

openssl_csr_sign 的限制

  • 在签名 CSR 时,过期日期是从当前日期/时间起的整数天数。
  • 在签名 CSR 时,无法设置不早于日期。这始终是当前日期/时间。

缺少的功能

  • 没有使用 altNames (#4) 的缩写

安全问题

  • 在 CSR 中无法过滤扩展,允许用户输入 CSR (#3) 存在风险

测试

make test

贡献

在提交之前,请运行

make camera-ready