openssl_csr_sign

(PHP 4 >= 4.2.0, PHP 5, PHP 7, PHP 8)

openssl_csr_signSign a CSR with another certificate (or itself) and generate a certificate

Description

openssl_csr_sign(
    OpenSSLCertificateSigningRequest|string $csr,
    OpenSSLCertificate|string|null $ca_certificate,
    #[\SensitiveParameter] OpenSSLAsymmetricKey|OpenSSLCertificate|array|string $private_key,
    int $days,
    ?array $options = null,
    int $serial = 0,
    ?string $serial_hex = null
): OpenSSLCertificate|false

openssl_csr_sign() generates an x509 certificate from the given CSR.

Note: You need to have a valid openssl.cnf installed for this function to operate correctly. See the notes under the installation section for more information.

Parameters

csr

A CSR previously generated by openssl_csr_new(). It can also be the path to a PEM encoded CSR when specified as file://path/to/csr or an exported string generated by openssl_csr_export().

ca_certificate

The generated certificate will be signed by ca_certificate. If ca_certificate is null, the generated certificate will be a self-signed certificate.

private_key

private_key is the private key that corresponds to ca_certificate.

days

days specifies the length of time for which the generated certificate will be valid, in days.

options

You can finetune the CSR signing by options. See openssl_csr_new() for more information about options.

serial

An optional the serial number of issued certificate. If not specified it will default to 0.

serial_hex

An optional hexadecimal string representing the serial number of the issued certificate. If set, it takes precedence over the serial parameter value. If not specified or set to null, the serial parameter value is used instead.

Return Values

Returns an OpenSSLCertificate on success, false on failure.

Changelog

Version Description
8.4.0 The serial_hex parameter is added.
8.0.0 On success, this function returns an OpenSSLCertificate instance now; previously, a resource of type OpenSSL X.509 was returned.
8.0.0 csr accepts an OpenSSLCertificateSigningRequest instance now; previously, a resource of type OpenSSL X.509 CSR was accepted.
8.0.0 ca_certificate accepts an OpenSSLCertificate instance now; previously, a resource of type OpenSSL X.509 was accepted.
8.0.0 private_key accepts an OpenSSLAsymmetricKey or OpenSSLCertificate instance now; previously, a resource of type OpenSSL key or OpenSSL X.509 was accepted.

Examples

Example #1 openssl_csr_sign() example - signing a CSR (how to implement your own CA)

<?php
// Let's assume that this script is set to receive a CSR that has
// been pasted into a textarea from another page
$csrdata = $_POST["CSR"];

// We will sign the request using our own "certificate authority"
// certificate. You can use any certificate to sign another, but
// the process is worthless unless the signing certificate is trusted
// by the software/users that will deal with the newly signed certificate

// We need our CA cert and its private key
$cacert = "file://path/to/ca.crt";
$privkey = array("file://path/to/ca.key", "your_ca_key_passphrase");

$usercert = openssl_csr_sign($csrdata, $cacert, $privkey, 365, array('digest_alg'=>'sha256') );

// Now display the generated certificate so that the user can
// copy and paste it into their local configuration (such as a file
// to hold the certificate for their SSL server)
openssl_x509_export($usercert, $certout);
echo
$certout;

// Show any errors that occurred here
while (($e = openssl_error_string()) !== false) {
echo
$e . "\n";
}
?>

add a note

User Contributed Notes 4 notes

up
0
thomas dot lussnig at bewegungsmelder dot de
22 years ago
Here is an sample how to create valid X.509 Public and Private Key (cert/key).
When not using self signed the 4.2.1 segault. You need the CVS code at least for openssl.

<?
Header("Content-Type: text/plain");
$CA_CERT = "CA.cert.pem";
$CA_KEY = "CA.key.pem";
$req_key = openssl_pkey_new();
if(openssl_pkey_export ($req_key, $out_key)) {
$dn = array(
"countryName" => "DE",
"stateOrProvinceName" => "Frankfurt",
"organizationName" => "smcc.net",
"organizationalUnitName" => "E-Mail",
"commonName" => "Testcert"
);
$req_csr = openssl_csr_new ($dn, $req_key);
$req_cert = openssl_csr_sign($req_csr, "file://$CA_CERT", "file://$CA_KEY", 365);
if(openssl_x509_export ($req_cert, $out_cert)) {
echo "$out_key\n";
echo "$out_cert\n";
}
else echo "Failed Cert\n";
}
else echo "FailedKey\n";
?>
up
-1
eric at ypass dot net
22 years ago
To generate a self-signed certificate, pass NULL as the signing certificate (2nd parameter). For example:

$req_key = openssl_pkey_new();
$dn = array(
"countryName" => "US",
"stateOrProvinceName" => "Colorado",
"organizationName" => "yPass.net",
"organizationalUnitName" => "yPass.net",
"commonName" => "yPass.net Root Certificate"
);
$req_csr = openssl_csr_new($dn, $req_key);
$req_cert = openssl_csr_sign($req_csr, NULL, $req_key, 365);
up
-2
Sriraam
9 years ago
config_section_section is incorrect. The correct keyword to use is "config_section_name".
up
-5
Kai Sellgren
15 years ago
You can use file_get_contents() to directly pass the content instead of giving file paths.

Also, if you get an error "sec_error_reused_issuer_and_serial", put a serial into the last parameter:

<?php

$privkey
= array(file_get_contents('ca.key'),"your_ca_key_passphrase");
$usercert = openssl_csr_sign($csrdata, file_get_contents('ca.crt'),$privkey,365,NULL,'06');
openssl_x509_export($usercert,$certout);
file_put_contents('serverCASigned.crt',$certout);

?>

In that above example the serial was "06".
To Top