Maison > développement back-end > Problème PHP > Comment implémenter l'authentification bidirectionnelle https en php

Comment implémenter l'authentification bidirectionnelle https en php

藏色散人
Libérer: 2023-03-04 08:46:01
original
4597 Les gens l'ont consulté

Comment implémenter https en PHP : modifiez d'abord la configuration openssl ; puis créez un certificat racine de l'autorité de certification, et définissez le mot de passe du certificat pour qu'il soit supérieur ou égal à 6 caractères, puis créez un certificat serveur et un certificat client ; ; enfin, configurez nginx et exécutez PHP. Il suffit de boucler le test.

Comment implémenter l'authentification bidirectionnelle https en php

Recommandé : "Tutoriel vidéo PHP"

php implémente https (tls/ssl) deux- authentification par voie

Normalement, lors du déploiement de https, elle est basée sur l'authentification unidirectionnelle SSL, ce qui signifie que tant que le client authentifie le serveur, le serveur n'a pas besoin d'authentifier le client.

Cependant, dans certains scénarios avec une sécurité plus élevée, tels que les domaines bancaires, financiers et autres, l'authentification du client est généralement requise. Cela permet une authentification bidirectionnelle de SSL.

Étant donné que le paramètre ssl_client_certificate de nginx ne peut spécifier qu'une seule clé publique client, si vous ajoutez un client pour la communication, vous devrez reconfigurer un serveur.

Le mode n:1 est implémenté via le mode de certificat en cascade de l'autorité de certification. Tout d'abord, générez vous-même un ensemble de certificats au niveau racine de l'autorité de certification, puis utilisez-le pour générer un certificat secondaire en tant que certificat client.

À ce stade, la signature de la clé privée du client peut être vérifiée non seulement par la clé publique du client correspondante, mais également par la clé publique du certificat racine.

Vous devriez être éclairé après avoir vu ceci. Voici une brève introduction sur le fonctionnement :

1 Préparation

1.1 Préparation du répertoire Openssl

Situation générale. Les fichiers de configuration d'openssl sont tous dans ce répertoire /etc/pki/tls, donc :

mkdir /etc/pki/ca_linvo
cd /etc/pki/ca_linvo
mkdir root server client newcerts
echo 01 > serial
echo 01 > crlnumber
touch index.txt
Copier après la connexion

1.2 préparation de la configuration openssl

Modifier la configuration openssl

vi /etc/pki / tls/openssl.cnf

Commentez cette phrase et remplacez-la par la phrase suivante

#default_ca      = CA_default
default_ca      = CA_linvo
Copier après la connexion

Copiez la partie entière de [CA_default] et remplacez-la par le nom ci-dessus [CA_linvo]

Modifiez les paramètres suivants à l'intérieur :

dir = /etc/pki/ca_linvo
certificate = $dir/root/ca.crt
private_key = $dir/root/ca.key
Copier après la connexion

Enregistrez et quittez

2 Créer un certificat de niveau racine de l'autorité de certification

生成key:openssl genrsa -out /etc/pki/ca_linvo/root/ca.key
生成csr:openssl req -new -key /etc/pki/ca_linvo/root/ca.key -out /etc/pki/ca_linvo/root/ca.csr
生成crt:openssl x509 -req -days 3650 -in /etc/pki/ca_linvo/root/ca.csr -signkey /etc/pki/ca_linvo/root/ca.key -out /etc/pki/ca_linvo/root/ca.crt
生成crl:openssl ca -gencrl -out /etc/pki/ca_linvo/root/ca.crl -crldays 7
Copier après la connexion

Les fichiers de certificat de niveau racine générés sont tous dans /etc/pki/

sous le répertoire ca_linvo/root/ Remarque : lors de la création d'un certificat, il est recommandé que le mot de passe du certificat soit défini sur une longueur >= 6 caractères, car l'outil Java keytool semble avoir exigences pour cela.

3 Créer un certificat de serveur

生成key:openssl genrsa -out /etc/pki/ca_linvo/server/server.key
生成csr:openssl req -new -key /etc/pki/ca_linvo/server/server.key -out /etc/pki/ca_linvo/server/server.csr
生成crt:openssl ca -in /etc/pki/ca_linvo/server/server.csr -cert /etc/pki/ca_linvo/root/ca.crt -keyfile /etc/pki/ca_linvo/root/ca.key -out /etc/pki/ca_linvo/server/server.crt -days 3650
Copier après la connexion

Instructions :

1. Le crt généré ici est le certificat en cascade sous le certificat racine ca à l'instant. principalement utilisé pour la configuration https unidirectionnel normal, vous pouvez donc le faire sans utiliser le mode cascade :

openssl rsa -in /etc/pki/ca_linvo/server/server.key -out /etc/pki/ca_linvo/server/server.key
openssl x509 -req -in /etc/pki/ca_linvo/server/server.csr -signkey /etc/pki/ca_linvo/server/server.key -out /etc/pki/ca_linvo/server/server.crt -days 3650
Copier après la connexion

2 Le paramètre -days peut définir la période de validité du certificat selon vos besoins, par exemple, la valeur par défaut est. 365 jours

4 Créer un certificat client

生成key:openssl genrsa -des3 -out /etc/pki/ca_linvo/client/client.key 1024
生成csr:openssl req -new -key /etc/pki/ca_linvo/client/client.key -out /etc/pki/ca_linvo/client/client.csr
生成crt:openssl ca -in /etc/pki/ca_linvo/client/client.csr -cert /etc/pki/ca_linvo/root/ca.crt -keyfile /etc/pki/ca_linvo/root/ca.key -out /etc/pki/ca_linvo/client/client.crt -days 3650
Copier après la connexion

Remarque :

1 Vous devez utiliser des certificats en cascade ici, et vous pouvez répéter cette étape pour créer plusieurs ensembles de certificats clients<. 🎜>

2. Vous pouvez rencontrer des problèmes lors de la génération de crt L'erreur suivante est signalée :

openssl TXT_DB error number 2 failed to update database
Copier après la connexion

Vous pouvez vous référer à l'opération ici.

J'utilise la première méthode, c'est-à-dire unique_subject = no

5 dans index.txt.attr pour configurer nginx

Seules les parties clés du segment de serveur sont répertoriées ici :

ssl_certificate  /etc/pki/ca_linvo/server/server.crt;#server公钥
ssl_certificate_key  /etc/pki/ca_linvo/server/server.key;#server私钥
ssl_client_certificate   /etc/pki/ca_linvo/root/ca.crt;#根级证书公钥,用于验证各个二级client
ssl_verify_client on;
Copier après la connexion

Redémarrer Nginx

6 tests

6.1 Test du navigateur

En raison de l'authentification bidirectionnelle, l'accès à l'adresse https directement via le navigateur sera entraîne une 400 Bad Request (aucun certificat SSL requis n'a été envoyé), le certificat client doit être installé sur la machine locale.

Le certificat installé sous Windows nécessite le format pfx, également appelé format p12. La méthode de génération est la suivante :

openssl pkcs12 -export -inkey /etc/pki/ca_linvo/client/client.key -in /etc/pki/ca_linvo/client/client.crt -out /etc/pki/ca_linvo/client/client.pfx
Copier après la connexion

Double-cliquez ensuite dessus dans Windows pour l'installer. sera invité à entrer l’heure de génération du mot de passe défini.

Une fois l'installation réussie, redémarrez le navigateur et entrez l'URL pour y accéder. Le navigateur peut vous demander de sélectionner un certificat. Sélectionnez simplement le certificat que vous venez d'installer.

À ce stade, certains navigateurs indiqueront à l'utilisateur que le certificat n'est pas fiable, que l'adresse n'est pas sécurisée, etc. En effet, notre certificat de serveur est émis par nous-mêmes, et non par une véritable organisation d'autorité de certification faisant autorité (généralement très cher ~), ignorez-le.

6.2 php curl test

Seuls les paramètres clés curl qui doivent être définis sont répertoriés ici :

curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 信任任何证书,不是CA机构颁布的也没关系  
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 1); // 检查证书中是否设置域名,如果不想验证也可设为0  
curl_setopt($ch, CURLOPT_VERBOSE, &#39;1&#39;); //debug模式,方便出错调试  
curl_setopt($ch, CURLOPT_SSLCERT, CLIENT_CRT); //client.crt文件路径,这里我用常量代替  
curl_setopt($ch, CURLOPT_SSLCERTPASSWD, CRT_PWD); //client证书密码  
curl_setopt($ch, CURLOPT_SSLKEY, CLIENT_KEY); //client.key文件路径  
 
CURLOPT_TIMEOUT:超时时间
CURLOPT_RETURNTRANSFER:是否要求返回数据
CURLOPT_SSL_VERIFYPEER:是否检测服务器的证书是否由正规浏览器认证过的授权CA颁发的
CURLOPT_SSL_VERIFYHOST:是否检测服务器的域名与证书上的是否一致
CURLOPT_SSLCERTTYPE:证书类型,"PEM" (default), "DER", and"ENG".
CURLOPT_SSLCERT:证书存放路径
CURLOPT_SSLCERTPASSWD:证书密码,没有可以留空
CURLOPT_SSLKEYTYPE:私钥类型,"PEM" (default), "DER", and"ENG".
CURLOPT_SSLKEY:私钥存放路径
 
 
function curl_post_ssl($url, $vars, $second=30,$aHeader=array())
{
    $ch = curl_init();
    //curl_setopt($ch,CURLOPT_VERBOSE,&#39;1&#39;);
    curl_setopt($ch,CURLOPT_TIMEOUT,$second);
    curl_setopt($ch,CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch,CURLOPT_URL,$url);
    curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,false);
    curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,false);
    curl_setopt($ch,CURLOPT_SSLCERTTYPE,&#39;PEM&#39;);
    curl_setopt($ch,CURLOPT_SSLCERT,&#39;/data/cert/php.pem&#39;);
    curl_setopt($ch,CURLOPT_SSLCERTPASSWD,&#39;1234&#39;);
    curl_setopt($ch,CURLOPT_SSLKEYTYPE,&#39;PEM&#39;);
    curl_setopt($ch,CURLOPT_SSLKEY,&#39;/data/cert/php_private.pem&#39;);
 
    if( count($aHeader) >= 1 ){
            curl_setopt($ch, CURLOPT_HTTPHEADER, $aHeader);
    }
 
    curl_setopt($ch,CURLOPT_POST, 1);
    curl_setopt($ch,CURLOPT_POSTFIELDS,$vars);
    $data = curl_exec($ch);
    curl_close($ch);
    if($data)
            return $data;
    else   
            return false;
}
Copier après la connexion

La vérification a échoué et les informations suivantes seront dans le nginx journal des erreurs

2017/06/05 17:45:07 [crit] 16084#0: *27458991 SSL_do_handshake() failed (SSL: error:04067084:rsa routines:RSA_EAY_PUBLIC_DECRYPT:data too large for modulus e
rror:1408807A:SSL routines:ssl3_get_cert_verify:bad rsa signature) while SSL handshaking, client: 116.255.208.194, server: 0.0.0.0:443
Copier après la connexion

6.3 php soap test

Vous devez d'abord créer le certificat au format pem du client. Vous pouvez également utiliser la commande openssl, mais comme nous avons déjà crt et key, la fusion manuelle est nécessaire. aussi très simple :

Créez un nouveau fichier et copiez le contenu base64 (y compris ces deux lignes de séparation) entre -----BEGIN CERTIFICATE----- et -----END CERTIFICATE--- -- dans crt., puis copiez le contenu entre -----BEGIN RSA PRIVATE KEY----- et -----END RSA PRIVATE KEY----- dans la clé, puis enregistrez-le en tant que client. .pem.

En fait, il est plus simple de fusionner les deux fichiers directement avec la commande suivante :

cat /etc/pki/ca_linvo/client/client.crt /etc/pki/ca_linvo/client/client.key > /etc/pki/ca_linvo/client/client.pem
Copier après la connexion

Avec le fichier pem, vous pouvez utiliser le SoapClient intégré en php pour l'appeler The. le constructeur doit définir le deuxième paramètre :

$header = array(          
    &#39;local_cert&#39; => CLIENT_PEM, //client.pem文件路径  
    &#39;passphrase&#39; => CRT_PWD //client证书密码  
    );  
$client = new SoapClient(FILE_WSDL, $header); //FILE_WSDL为要访问的https地址
Copier après la connexion
Dans le dernier blog, il a été mentionné que si local_cert est défini sur un chemin distant, une erreur sera signalée. Il semble que le certificat client ne soit pas utilisé lors de l'obtention. le wsdl pour la première fois, et le wsdl doit être conservé en tant que fichier local

Mais il n'y a eu aucun problème dans ce test. Il n'est pas nécessaire de le sauvegarder en tant que fichier local, il suffit de le récupérer. cela à distance.

Au départ, je pensais qu'il y avait un problème avec le certificat précédent, mais je peux toujours utiliser l'ensemble de certificats précédent, ce qui est très étrange~~~~~

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal