PHP 8.4.0 RC4 available for testing

openssl_csr_new

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

openssl_csr_newGénère une CSR

Description

openssl_csr_new(
    array $distinguished_names,
    #[\SensitiveParameter] ?OpenSSLAsymmetricKey &$private_key,
    ?array $options = null,
    ?array $extra_attributes = null
): OpenSSLCertificateSigningRequest|bool

openssl_csr_new() génère une nouvelle CSR, requête de signature de certificat), basée sur les informations apportés par distinguished_names.

Note: Vous devez avoir un fichier openssl.cnf valide et installé pour que cette fonction opère correctement. Voir les notes se trouvant dans la section concernant l'installation pour plus d'informations.

Liste de paramètres

distinguished_names

Le nom distingué ou champs de sujets qui doit être utilisé dans le certificat.

private_key

private_key doit être une clé privée qui a été générée par openssl_pkey_new() (ou obtenue autrement par l'une des fonctions de la famille openssl_pkey) , ou la variable null. Si sa valeur est une variable null, une nouvelle clé privée est générée en fonction des options fournies et assignée à la variable fournie. La partie publique correspondante de la clé sera utilisée pour signer le CSR.

options

Par défaut, le fichier openssl.conf de votre système est utilisé pour initialiser la requête; vous pouvez spécifier une section du fichier de configuration en paramétrant la clé config_section_section dans options. Vous pouvez aussi spécifier un fichier de configuration OpenSSL alternatif en paramétrant la valeur de config avec le chemin du fichier à utiliser. Si les clés suivantes sont présentes dans options, elles se comportent comme leurs équivalents dans openssl.conf, selon la liste suivante.

Écrasement de configuration
options type Équivalent de openssl.conf description
digest_alg string default_md Méthode de digeste ou signature de hachage, généralement un de openssl_get_md_methods()
x509_extensions string x509_extensions Sélectionne quelle extension utiliser lors de la création d'un certificat x509
req_extensions string req_extensions Sélectionne quelle extension utiliser lors de la création d'une CSR
private_key_bits int default_bits Spécifie la longueur en bits de la clé privée
private_key_type int none Spécifie le type de clé privée à créer. Cela peut être l'un de OPENSSL_KEYTYPE_DSA, OPENSSL_KEYTYPE_DH, OPENSSL_KEYTYPE_RSA ou OPENSSL_KEYTYPE_EC. La valeur par défaut est OPENSSL_KEYTYPE_RSA.
encrypt_key bool encrypt_key La clé (avec mot de passe) exportée doit-elle être chiffrée?
encrypt_key_cipher int none Une des constantes cipher.
curve_name string none Un de openssl_get_curve_names().
config string N/A Chemin vers votre fichier openssl.conf alternatif.

extra_attributes

extra_attributes est utilisé pour spécifier des options de configuration supplémentaires pour la CSR. Les distinguished_names et extra_attributes sont tous deux des tableaux associatifs, dont les clés sont converties en OID et appliquées à la partie pertinente de la requête.

Valeurs de retour

Retourne le CSR en cas de succès, true si la création du CSR réussit mais que la signature échoue ou false si une erreur survient.

Historique

Version Description
8.0.0 csr accepte désormais une instance de OpenSSLCertificateSigningRequest ; auparavant, une ressource de type OpenSSL X.509 CSR était acceptée.
8.0.0 En cas de succès, cette fonction retourne désormais une instance de OpenSSLAsymmetricKey ; auparavant une ressource de type OpenSSL key était retournée.
7.1.0 options supporte désormais curve_name.

Exemples

Exemple #1 Création d'un certificat autosigné

<?php
// pour les certificats SSL serveur, le commonName est le nom de domaine à sécuriser
// pour les certificats e-mail S/MIME le commonName est le propriétaire de l'adresse e-mail
// les champs d'emplacement et d'identification font référence au propriétaire du domaine ou à l'objet de l'e-mail à sécuriser
$dn = array(
"countryName" => "GB",
"stateOrProvinceName" => "Somerset",
"localityName" => "Glastonbury",
"organizationName" => "The Brain Room Limited",
"organizationalUnitName" => "PHP Documentation Team",
"commonName" => "Wez Furlong",
"emailAddress" => "wez@example.com"
);

// Génère une nouvelle paire de clés privée (et publique)
$privkey = openssl_pkey_new(array(
"private_key_bits" => 2048,
"private_key_type" => OPENSSL_KEYTYPE_RSA,
));

// Génère une requête de signature de certificat
$csr = openssl_csr_new($dn, $privkey, array('digest_alg' => 'sha256'));

// Génère un certificat autosigné, valide pour 365 jours
$x509 = openssl_csr_sign($csr, null, $privkey, $days=365, array('digest_alg' => 'sha256'));

// Conservez votre clé privée, CSR et certificat autosigné pour une utilisation ultérieur
openssl_csr_export($csr, $csrout) and var_dump($csrout);
openssl_x509_export($x509, $certout) and var_dump($certout);
openssl_pkey_export($privkey, $pkeyout, "mypassword") and var_dump($pkeyout);

// Affiche les erreurs qui sont survenues
while (($e = openssl_error_string()) !== false) {
echo
$e . "\n";
}
?>

Exemple #2 Créer un certficat ECC autosigné (à partir de PHP 7.1.0)

<?php
$subject
= array(
"commonName" => "docs.php.net",
);

// Génère une nouvelle paire de clés privée (et publique)
$private_key = openssl_pkey_new(array(
"private_key_type" => OPENSSL_KEYTYPE_EC,
"curve_name" => 'prime256v1',
));

// Génère une requête de signature de certificat
$csr = openssl_csr_new($subject, $private_key, array('digest_alg' => 'sha384'));

// Génère un certificat EC autosigné
$x509 = openssl_csr_sign($csr, null, $private_key, $days=365, array('digest_alg' => 'sha384'));
openssl_x509_export_to_file($x509, 'ecc-cert.pem');
openssl_pkey_export_to_file($private_key, 'ecc-private.key');
?>

Voir aussi

  • openssl_csr_sign() - Signe un CSR avec un autre certificat (ou lui-même) et génère un certificat

add a note

User Contributed Notes 10 notes

up
11
The_Lost_One
15 years ago
Not sure whether the "bug" (undocumented behavior) I encountered is common to other people, but this comment might save hours of painful debug:
If you can't generate a new private key using openssl_pkey_new() or openssl_csr_new(), your script hangs during the call of these functions and in case you specified a "private_key_bits" parameter, ensure that you cast the variable to an int. Took me ages to notice that.

<?php
$SSLcnf
= array('config' => '/usr/local/nessy2/share/ssl/openssl.cnf',
'encrypt_key' => true,
'private_key_type' => OPENSSL_KEYTYPE_RSA,
'digest_alg' => 'sha1',
'x509_extensions' => 'v3_ca',
'private_key_bits' => $someVariable // ---> bad
'private_key_bits' => (int)$someVariable // ---> good
'private_key_bits' => 512 // ---> obviously good
);
?>
up
6
james at kirk dot com
9 years ago
When in doubt, read the source code to PHP!

$configargs is fairly opaque as to what is going on behind the scenes. That is, until you actually look at php_openssl_parse_config() in '/ext/openssl/openssl.c':

SET_OPTIONAL_STRING_ARG("digest_alg", req->digest_name,
CONF_get_string(req->req_config, req->section_name, "default_md"));
SET_OPTIONAL_STRING_ARG("x509_extensions", req->extensions_section,
CONF_get_string(req->req_config, req->section_name, "x509_extensions"));
SET_OPTIONAL_STRING_ARG("req_extensions", req->request_extensions_section,
CONF_get_string(req->req_config, req->section_name, "req_extensions"));
SET_OPTIONAL_LONG_ARG("private_key_bits", req->priv_key_bits,
CONF_get_number(req->req_config, req->section_name, "default_bits"));

SET_OPTIONAL_LONG_ARG("private_key_type", req->priv_key_type, OPENSSL_KEYTYPE_DEFAULT);

Here we can see that SET_OPTIONAL_STRING_ARG() is called for most inputs but for 'private_key_bits' SET_OPTIONAL_LONG_ARG() is called. Both calls are C macros that expand to code that enforces the expected input type. The generated code ignores the input without warning/notice if an unexpected type is used and just uses the default from the configuration file. This is why using a string with 'private_key_bits' will result in unexpected behavior.

Further inspection of the earlier initialization in the same function:

SET_OPTIONAL_STRING_ARG("config", req->config_filename, default_ssl_conf_filename);
SET_OPTIONAL_STRING_ARG("config_section_name", req->section_name, "req");
req->global_config = CONF_load(NULL, default_ssl_conf_filename, NULL);
req->req_config = CONF_load(NULL, req->config_filename, NULL);

if (req->req_config == NULL) {
return FAILURE;
}

And elsewhere in another function:

/* default to 'openssl.cnf' if no environment variable is set */
if (config_filename == NULL) {
snprintf(default_ssl_conf_filename, sizeof(default_ssl_conf_filename), "%s/%s",
X509_get_default_cert_area(),
"openssl.cnf");
} else {
strlcpy(default_ssl_conf_filename, config_filename, sizeof(default_ssl_conf_filename));
}

Reveals that 'config' in $configargs is an override for any default setting elsewhere. This actually negates the comment in the documentation that says "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." A more correct sentence would be "Note: You need to either have a valid openssl.cnf set up or use $configargs to point at a valid openssl.cnf file for this function to operate correctly."

All of that goes to show that looking at the PHP source code is the only real way to figure out what is actually happening. Doing so saves time and effort.
up
3
Anonymous
9 years ago
For those of you using Debian-based systems, the openssl configuration file is at: /etc/ssl/openssl.cnf
up
2
main ATT jokester DOTT fr
16 years ago
To set the "basicConstraints" to "critical,CA:TRUE", you have to define configargs, but in the openssl_csr_sign() function !

That's my example of code to sign a "child" certificate :

$CAcrt = "file://ca.crt";
$CAkey = array("file://ca.key", "myPassWord");

$clientKeys = openssl_pkey_new();
$dn = array(
"countryName" => "FR",
"stateOrProvinceName" => "Finistere",
"localityName" => "Plouzane",
"organizationName" => "Ecole Nationale d'Ingenieurs de Brest",
"organizationalUnitName" => "Enib Students",
"commonName" => "www.enib.fr",
"emailAddress" => "ilovessl@php.net"
);
$csr = openssl_csr_new($dn, $clientPrivKey);

$configArgs = array("x509_extensions" => "v3_req");
$cert = openssl_csr_sign($csr, $CAcrt, $CAkey, 100, $configArgs);

openssl_x509_export_to_file($cert, "childCert.crt");

Then if you want to add some more options, you can edit the "/etc/ssl/openssl.cnf" ssl config' file (debian path), and add these after the [ v3_req ] tag.
up
3
alex at nodex dot co dot uk
9 years ago
In the PHP example above it uses "UK" as the country name which is incorrect, the country name must be "GB"
up
0
Richard Lynch
11 years ago
There appears to be no openssl_csr_free function.

At least not here.

If it's in the source, one might be able to just call it.

If it's not in the source, it probably should be.
up
0
Anonymous
19 years ago
If you get the error:

error:0D11A086:asn1 encoding routines:ASN1_mbstring_copy:string too short

then look at your key:value pairs in the $dn (distinguished name) array.

If you have one value (like "organizationalUnitName" = "") set to an empty string, it will throw the above error.

Fix the error by either eliminating that array element from $dn completely, or using a space " " instead of an empty string.
up
0
robertliu AT wiscore DOT com
19 years ago
I am using PHP-4.3.11.
The type of configargs--private_key_bits is a INTEGER, not a string.
An example of configration:
<?php
$config
= array(
"digest_alg" => "sha1",
"private_key_bits" => 2048,
"private_key_type" => OPENSSL_KEYTYPE_DSA,
"encrypt_key" => false
);
?>
up
-1
dankybastard at hotmail
19 years ago
As you probably guessed from the example, the documentation is misinforming. openssl_csr_new returns a CSR resource or FALSE on failure.

mixed openssl_csr_new (assoc_array dn, resource_privkey, [...])
up
-1
@operator
7 years ago
One command to create modern certificate request with 4 SAN subdomain.
According to RFC you can change CN (common name) and subjectAltName. When cert validated searching in CN and subjectAltName.

openssl req -new -nodes -config <( cat <<-EOF
[req]
default_bits = 2048
prompt = no
default_md = sha256
req_extensions = re
distinguished_name = dn
[ dn ]
CN = my.tld
C = country
ST = state
L = location
O = ORGANISATION
[ re ]
subjectAltName = DNS.1: www.my.tld, DNS.2: www2.my.tld, DNS.3: www3.my.tld, DNS.4: www4.my.tld
EOF
) -keyout secret.key -out req.csr
To Top